这个问题在某种程度上是对相关帖子的说明,我相信下面的示例描述了问题的本质。
class Program
{
public static IList<string> GetData(string arg)
{
return new string[] {"a", "b", "c"};
}
static void Main(string[] args)
{
var arg1 = "abc";
var res1 = GetData(arg1);
Console.WriteLine(res1.Count());
dynamic arg2 = "abc";
var res2 = GetData(arg2);
try
{
Console.WriteLine(res2.Count());
}
catch (RuntimeBinderException)
{
Console.WriteLine("Exception when accessing Count method");
}
IEnumerable<string> res3 = res2;
Console.WriteLine(res3.Count());
}
}
对 GetData 的第二次调用仅因为 GetData 收到转换为动态的参数而引发异常,这不是很糟糕吗?该方法本身可以使用这样的参数:它将其视为字符串并返回正确的结果。但是结果又被强制转换为动态,结果数据突然无法根据其底层类型进行处理。除非它被显式地转换回静态类型,正如我们在示例的最后几行中看到的那样。
我不明白为什么必须以这种方式实施。它破坏了静态和动态类型之间的互操作性。一旦使用动态,它就会感染调用链的其余部分,可能会导致类似这样的问题。
更新。有人指出 Count() 是扩展方法,不被识别是有道理的。然后我将调用 res2.Count() 更改为 res2.Count(从扩展方法更改为 Ilist 的属性),但程序在同一个地方引发了相同的异常!现在这很奇怪。
更新2。flq 指出了 Eric Lippert 关于这个主题的博客文章,我相信这篇文章为它为什么以这种方式实现提供了充分的理由:http: //blogs.msdn.com/b/ericlippert/archive/2012/10/22/a -method-group-of-one.aspx