给出这个简短的示例程序:
static void Main(string[] args)
{
Console.WriteLine(Test("hello world"));
}
private static int Test(dynamic value)
{
var chars = Chars(value.ToString());
return chars.Count();
}
private static IEnumerable<char> Chars(string str)
{
return str.Distinct();
}
运行时,它将产生类似于以下内容的异常:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ''object' does not contain a definition for 'Count''
含义编译器选择dynamic
作为首选chars
变量类型。
IEnumerable<char>
考虑到动态不是从Chars
方法返回的,是否有任何理由不选择它作为具体类型?只需手动更改类型即可IEnumerable<char>
解决问题,但是我想知道为什么dynamic
在这种情况下使用默认值?
编辑
我可能使用了比必要的例子更复杂的例子。看来这里的问题是:
提供了更简洁的示例,以及有关其工作方式的一些见解。
https://blogs.msdn.microsoft.com/ericlippert/2012/11/05/dynamic-contagion-part-one/
描述编译器如何处理动态。
使用dynamic
,所有方法调用都在运行时解决。因此,它拒绝什么方法,当你调用实际上是被称为编译时猜测Chars()
,Count()
或甚ToString()
。它可以是任何东西,返回任何东西。这通常被称为“动态传染”。
就编译器所知,somtimesvalue.ToString()
将返回MyRandomPOCOClass
,并且在运行时它将能够挖掘出一些重载,例如Tuple<int,String> Chars(MyRandomPOCOClass x)
。也许下次value.ToString()
会回来int
。所有赌注都关闭了。dynamic
将C#转换为脚本语言。
这是动态运行时过载行为的示例(这是一个小提琴):
public static void Main()
{
dynamic x = "foo";
Test(x);
x = 34;
Test(x);
}
public static void Test(string s)
{
Console.WriteLine("String " + s);
}
public static void Test(int n)
{
Console.WriteLine("Int " + n);
}
输出:
String foo
Int 34
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句