C# 混淆隐式类型变量与动态

C# Confounding Implicitly typed variable with dynamic

如果你 运行 TestClass.Test() 你会得到一个 RuntimeBinderException。这一切都始于 var str = DoSomething(obj); 隐式键入动态而不是字符串。有人可以解释这里发生了什么吗?为什么 RequiresString(str); 有效?我知道你不能在动态对象上调用扩展方法,但整个事情对我来说感觉有点肮脏和破碎。尽管存在明显的类型不匹配然后在 运行 时失败,但它都可以正常编译。

public static class ExtensionTest
{
    public static string ToJsonTest(this object x)
    {
        return string.Empty;
    }
}
public static class TestClass
{
    public static void Test()
    {
        dynamic obj = new ExpandoObject();
        obj.var1 = "hello";

        var str = DoSomething(obj);
        var testObj = RequiresString(str);
        var json = testObj.ToJsonTest();
    }
    public static string DoSomething(object x)
    {
        return string.Empty;
    }
    public static TestObj RequiresString(string x)
    {
        return new TestObj();
    }
    public class TestObj
    {
        public int Prop1 { get; set; }
    }
}

RequiresString 的调用包含 dynamic 个参数,因此 在运行时 使用实际参数的类型对其进行了解析。 DoSomething实际返回的类型是string,所以runtime binder寻找RequiresString(string),可以成功找到为TestClass.RequiresString。到目前为止,还不错。

下一次调用 testObj.ToJsonTest() 失败,正如您已经提到的,因为 dynamic 上的扩展方法以 are not resolved 为目标,所以下一次调用失败。

是的,它可能感觉有点脏,因为当涉及 dynamic 时(几乎)没有编译时检查,非常像弱类型脚本语言。这就是为什么我建议仅在确实需要且在尽可能狭窄的上下文中使用 dynamic 的原因;特别是,我会说 dynamic 不应在 class' public 表面上看到。