为什么在调用 IEnumerable.Contains() 时需要转换动态对象?

Why do I need to cast a dynamic object when calling IEnumerable.Contains()?

我正在尝试使用 dynamic 参数调用 IEnumerable.Contains(),但出现错误

'IEnumerable' does not contain a definition for 'Contains' and the best extension method overload 'Queryable.Contains(IQueryable, TSource)' has some invalid arguments

我注意到我可以将参数转换为正确的类型,或者使用底层集合类型来解决问题。但是我不确定为什么我不能直接传入参数。

dynamic d = "test";
var s = new HashSet<string>();
IEnumerable<string> ie = s;

s.Contains(d);           // Works
ie.Contains(d);          // Does not work
ie.Contains((string)d);  // Works

Enumerable.Contains 是一种扩展方法 - 扩展方法不会由在执行时使用的微型编译器解析。 (扩展方法依赖于 using 指令,这些指令没有被保留。它们可能被保留,但我想这被认为有点痛苦。)这包括使用 dynamic 扩展方法的参数,关于将它们用作扩展方法的"target"。

直接指定扩展方法即可:

var result = Enumerable.Contains(ie, d);