我知道它有点拗口,可能不完全可以理解。所以这是我想要做的一个例子。
public class TypeWithString
{
public string MyString { get; set; }
}
string s = "We Want Moshiach Now";
TypeWithString tws = new TypeWithString();
object o = s;
dynamic d = tws;
d.MyString = o;
此代码令人惊讶地生成错误RuntimeBinderException: Cannot implicitly convert type 'object' to 'string'
。
即使MyString
的类型为string
,o
中的内容仍为string
。
这是DLR中的错误还是缺点?
有没有办法绕过它?
如果我提前不知道这种类型。但我确实知道它符合鸭子打字。即我知道它实现了一个不成文的界面。无论如何,当它们确实是正确的类型时,我可以将一个变量分配给另一个变量吗?
非常感谢
答案 0 :(得分:4)
不,这是预期的。编译器知道o
的类型是object
,因此它记录了“尝试查找名为MyString
的属性的动态操作,然后尝试分配类型{{1}的值“它” - 如果有object
到object
的隐式转换,它可以这样做,但没有。请注意,语句的唯一部分是动态的 target ...所以这是动态处理的唯一位。在执行时,“执行时编译器”会有效地说:“string
的值的实际类型是什么?啊,它是TypeWithString ...现在,如果我们有这样的话会发生什么:
d
......会发生什么是编译时错误。
如果您希望它在值中动态运行,只需使用TypeWithString tmpD = (TypeWithString) d;
tmpD.MyObject = o;
而不是dynamic
作为您指定的值:
object
这次,“执行时编译器”会询问自己string s = "We Want Moshiach Now";
TypeWithString tws = new TypeWithString();
dynamic o = s;
dynamic d = tws;
d.MyString = o;
和 d
值的实际类型,并设想这样的代码:
o
答案 1 :(得分:1)
你总是可以尝试d.MyString = o as string;
,它会将(不抛出)o投射到一个字符串上,如果不存在,则为null。