【问题标题】:Case-Insensitive List.Contains(): No overload for method 'Contains' takes 2 arguments不区分大小写的 List.Contains():方法“包含”没有重载需要 2 个参数
【发布时间】:2019-08-08 13:18:58
【问题描述】:

C# 不区分大小写的 List.Contains():方法“包含”没有重载需要 2 个参数

如果我们这样做会得到编译器错误

list.Contains(stringToSearchDynamic.ToString(), StringComparer.OrdinalIgnoreCase)

但是如果我们输入实际的字符串,编译就可以了

list.Contains(stringToSearch, StringComparer.OrdinalIgnoreCase)

这是编译器错误吗?

代码:

List<string> list = new List<string>();
list.Add("one");
list.Add("two");

string stringToSearch = "OnE";
dynamic stringToSearchDynamic = "OnE";

//compiles OK
bool isContained = list.Contains(stringToSearch, StringComparer.OrdinalIgnoreCase);


//Does NOT compile
isContained = list.Contains(stringToSearchDynamic.ToString(), StringComparer.OrdinalIgnoreCase);

【问题讨论】:

  • 首先,没有必要将ToString()字符串一起使用。它本质上是一个返回字符串本身的空操作。如果字符串作为对象传递,一个简单的强制转换就足够了
  • 只是为了更清楚
  • @LydonCh 演员表总是更清晰。在这种情况下,它会完全避免这个问题
  • @PanagiotisKanavos 你是对的,演员表也有效,因为它告诉编译器它是什么类型。所以如果我做 list.Contains( (stringToSearchDynamic as string), StringComparer.OrdinalIgnoreCase)

标签: c#


【解决方案1】:

dynamic 表达式的类型也是动态的。由于您有一个动态变量,variable.ToString 的类型在运行时解析,而不是在编译时解析。所以它被视为dynamic,编译器找不到将dynamic作为第一个参数的Contains方法。

您可以按照 cmets 中的建议强制转换为 string,它之所以有效,是因为强制转换是编译时的事情,并使编译器将您的变量视为字符串。

【讨论】:

  • @PanagiotisKanavos 想详细说明为什么?
  • 错误文本本身抱怨Contains 有两个参数,而不是类型不匹配。现在我想到了,List.Contains() 只使用 one 参数。 OP 尝试使用 Enumerable.Contains 但编译器尝试使用 List.Contains 代替
  • 如果您尝试使用 int,您仍然会收到相同的错误消息:list.Contains(2, StringComparer.OrdinalIgnoreCase); 编译器首先搜索实例方法,然后搜索扩展方法,但由于没有将动态作为第一个参数的方法生成这个错误。
【解决方案2】:

使用简单的演员表代替ToString()。无论如何,ToString() 在应用于字符串实例时本质上是无操作的,它只返回字符串本身。这编译:

isContained = list.Contains((string)stringToSearchDynamic, StringComparer.OrdinalIgnoreCase);

说明

原始代码尝试使用Enumerable.Contains 扩展方法,该方法接受比较器作为第二个参数。该方法的签名是Contains&lt;TSource&gt;(IEnumerable&lt;TSource&gt;, TSource, IEqualityComparer&lt;TSource&gt;)。这意味着要搜索的值本身必须是 TSource。但在这种情况下,它是 dynamic,直到运行时才知道。

编译器甚至不会尝试使用扩展方法并尝试在 List 本身上查找 Contains。但它发现的是一个List.Contains(T),它只接受一个单个参数并抱怨多个参数

【讨论】:

    【解决方案3】:

    我使用的是 .NetFrameWork 4.7.2,它工作正常,但由于某些原因,我不得不使用 .NetFrameWork 2.0,而这里出现了类似的错误。因此,如果您可以使用最新的框架版本,它会有所帮助。

    【讨论】:

      【解决方案4】:

      请注意,如果您在没有合理解释的情况下遇到此错误,则此行为已从 .NET 标准 2.0 => 2.1 更改。因此,如果您正在使用 .NET Standard 2.0 或 .NET Framework 解决方案,则实际上不存在这种重载。

      解决方案可以是使用解决方法(例如,创建您自己的扩展方法),或将解决方案更新到 .NET Standard 2.1。对于这个用例来说,第二个选项听起来有点矫枉过正,并且与 .NET Framework 解决方案不兼容。

      【讨论】:

        猜你喜欢
        • 2016-11-15
        • 2014-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-23
        • 1970-01-01
        • 2013-01-16
        相关资源
        最近更新 更多