无法通过 Linq 方法 Contains() 针对 char 数组检查字符串,因为该数组不是 String 类型,转换为 String 类型失败

Posted

技术标签:

【中文标题】无法通过 Linq 方法 Contains() 针对 char 数组检查字符串,因为该数组不是 String 类型,转换为 String 类型失败【英文标题】:Cannot check a string against a char array through Linq method Contains() because the array isn't of type String, conversion to String type fails 【发布时间】:2020-11-28 04:44:51 【问题描述】:

我尝试将我检查的本地 charItem 变量转换为 String 类型,但这似乎并没有解决问题。我能做什么?

using System.IO;
using System;
using System.Linq;
using System.Collections.Generic;

class Program

    public static string ValidatePassword(string myPassword)
    
        char[] alphabetUpper  =   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z';
        char[] alphabetLower  =   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z';
        char[] digits     =   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9';
        char[] symbols    =   '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '+', '=', '_', '-', '', '', '[', ']', ':', ';', '\"', '\'', '?', '<', '>', ',', '.';
        
        ushort countUpper   =   0;  // Tracks uppercase characters.
        ushort countLower   =   0;  // Tracks lowercase characters.
        ushort countDigits  =   0;  // Tracks digits.
        ushort countSymbols =   0;  // Tracks symbols.
        
        bool repeatingCharacters = false; // Tracks repeated characters.
        
        if (myPassword.Length >= 6 || myPassword.Length <= 24)  // First, check if the length matches the range. If this succeeds, check for uppercase.
        
            foreach (char charItem in myPassword)
            
                if (alphabetUpper.Any(charItem.Contains))       // This checks for uppercase.
                countUpper++; 
            

...

    static void Main()
    
        System.Console.WriteLine(ValidatePassword("abc123ABC"));
    

错误:

main.cs(27,48): error CS1061: Type `char' does not contain a definition for `Contains' and no extension method `Contains' of type `char' could be found. Are you missing `System.Linq' using directive?

【问题讨论】:

如果您使用List&lt;char&gt;,则仅alphabetUpper.Contains(charItem) 是正确的条件...最终countUpper = myPassword.Count(alphabetUpper.Contains);,您甚至不必自己编写循环。 【参考方案1】:

您的 Any() 方法应该如下所示,因为 charItem 本身是 pf 类型 char 并且您实际上是在尝试将其与 char 数组中的值匹配

alphabetUpper.Any(x => x == charItem)

【讨论】:

谢谢!这很有帮助!【参考方案2】:

你所要做的就是:

foreach (char charItem in myPassword)

   if (Char.IsUpper(charItem))
   
       countUpper++;
   

你不需要数组。

【讨论】:

甚至countUpper = myPassword.Count(Char.IsUpper); ...假设他想要IsUpper的内置定义,其中可能包含外来字符的大写版本。【参考方案3】:

您可以使用以下块返回密码验证。 另外,我会将验证函数的返回类型从string 更改为bool

return myPassword.Length >= 6 && myPassword.Length <= 24 &&
                myPassword.Any(x => alphabetUpper.Contains(x)) &&
                myPassword.Any(x => alphabetLower.Contains(x)) &&
                myPassword.Any(x => digits.Contains(x)) &&
                myPassword.Any(x => symbols.Contains(x)) &&
                myPassword.Where((c, i) => i > 0 && c == myPassword[i - 1]).Count() == 0;

此代码块验证密码在每个数组中至少出现一次。 (一个小写、一个大写、一个数字和一个特殊字符)以及长度大于 5 小于 25。它还会检查以确保字符串中没有重复字符。

您也不必对这个 linq 语句使用任何循环。

重复字符函数取自here

【讨论】:

【参考方案4】:

由于您的循环变量是 char,因此您可以使用 == 运算符直接将其与数组中的字符进行比较:

if (alphabetUpper.Any(c => c == charItem)) countUpper++;

但是,您可能想做的一件事是使用 for 循环遍历项目,这样我们就可以通过访问 char 数组中下一个索引处的项目来检查重复字符(假设通过“重复字符" 你的意思是当前字符后面的字符是相同的)。

例如:

for(int i = 0; i < myPassword.Length;i++)

    var charItem = myPassword[i];

    if (alphabetUpper.Any(c => c == charItem)) countUpper++;
    else if (alphabetLower.Any(c => c == charItem)) countLower++;
    else if (digits.Any(c => c == charItem)) countDigits++;
    else if (symbols.Any(c => c == charItem)) countSymbols++;

    // Here we can check if this is a repeating character by accessing
    // the previous character using the 'i' index and subtracting one
    if (i > 0 && myPassword[i - 1] == charItem) repeatingCharacters = true;

【讨论】:

以上是关于无法通过 Linq 方法 Contains() 针对 char 数组检查字符串,因为该数组不是 String 类型,转换为 String 类型失败的主要内容,如果未能解决你的问题,请参考以下文章

Linq:int类型使用Contains方法

在 Linq 方法中使用对象/方法名称? [复制]

如何使用 LINQ Contains(string[]) 而不是 Contains(string)

Linq-Contains查询

针对 SQL 后端的 LINQ 的可扩展包含方法

LINQ Fluent NHIBERNATE .Contains() 在 QueryOver<> 中不起作用,但在 Query<> 中起作用