无法通过 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<char>
,则仅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 Contains(string[]) 而不是 Contains(string)
LINQ Fluent NHIBERNATE .Contains() 在 QueryOver<> 中不起作用,但在 Query<> 中起作用