为什么编译器会推断var为动态而不是具体类型?

亚历克斯

给出这个简短的示例程序:

    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在这种情况下使用默认值?

编辑

我可能使用了比必要的例子更复杂的例子。看来这里的问题是:

使用“ var”和“ dynamic”时出现异常

提供了更简洁的示例,以及有关其工作方式的一些见解。

https://blogs.msdn.microsoft.com/ericlippert/2012/11/05/dynamic-contagion-part-one/

描述编译器如何处理动态。

15ee8f99-57ff-4f92-890c-b56153

使用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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么编译器不推断impl trait返回值的关联类型的具体类型?

为什么编译器无法推断这种类型?

为什么编译器会自动为匿名类型生成Debugger属性?

为什么在使用decltype时,编译器为什么不推断成员的类型?

为什么Scala编译器不使用抽象类型来推断类型

为什么在我编写PairDStreamFunctions.reduceByKey时Scala编译器无法推断类型

为什么Rust编译器在调用parse时不能推断类型?

为什么Haskell编译器可以推断出这种类型,但是ghci不能?

为什么编译器不能(或不能)推断static_cast的类型参数?

为什么编译器不能为自定义集合推断循环变量类型?

在这种情况下,为什么F#编译器无法推断类型?

为什么C#编译器无法推断出返回值的类型参数?

为什么编译器不能推断出返回类型?

为什么这会混淆F#编译器的类型推断?

故障保险withFallback():为什么kotlin编译器无法推断lambda类型?

为什么OCaml编译器会给出有关类型推断的错误消息?

为什么编译器为特征及其实现推断不同的生存期?

为什么编译器和运行时假设字符串返回类型为动态?

为什么编译器不推断泛型

为什么编译器在具有双界泛型类型时不将 T(interface) 推断为实现 T 的类?

如何使用类型,为什么编译器会抱怨无限类型?

当编译器可以推断类型时,为函数使用类型签名的充分理由是什么?

为什么编译器不允许我们使用 `var` 而不是 `generic type`?

为什么编译器会尝试实例化错误的 STL 模板?(BinaryOperation 而不是 UnaryOperation)

为什么打字稿会推断“从不”而不是交点类型?

为什么此嵌套的通用类型转换会导致编译器错误

为什么编译器会抛出“期望的类型说明符”?

为什么Java编译器会抱怨将foreach与原始类型一起使用?

为什么Scala编译器会两次识别通用类型