如果运行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; }
}
}
答案 0 :(得分:2)
对RequiresString
的调用包含dynamic
个参数,因此它会在运行时使用实际参数的类型在上解析。 DoSomething
返回的实际类型是string
,因此运行时绑定程序将查找RequiresString(string)
,可以成功找到TestClass.RequiresString
。到目前为止,一切都很好。
正如您已经提到的,下一次调用testObj.ToJsonTest()
失败,因为dynamic
上的扩展方法以are not resolved为目标,所以下一次调用失败。
是的,可能会感到有点脏,因为涉及dynamic
时几乎没有编译时检查,这与弱类型脚本语言非常相似。这就是为什么我建议仅在确实需要且在尽可能狭窄的环境中使用dynamic
的原因;特别是,我会说dynamic
不应在全班公开场合露面。