4

我知道它有点拗口,可能无法完全理解。所以这是我正在尝试做的一个例子。

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,并且被保存的ostring.

这是 DLR 中的错​​误还是缺点?

有没有办法绕过它?

如果我提前不知道类型。但我确实知道它符合鸭子类型。即我知道它实现了一个不成文的接口。无论如何,当它们确实是正确的类型时,我可以将一个变量分配给另一个变量吗?

非常感谢

4

2 回答 2

4

不,这是意料之中的。编译器知道ois的类型object,因此它记录了“尝试查找调用的属性MyString,然后尝试为其分配一个类型的值”的动态操作 - 如果存在toobject的隐式转换,它可以这样做,但是有不是。请注意,您的语句中唯一动态的部分是它的目标......所以这是唯一被动态处理的部分。在执行时,“执行时编译器”会有效地说,“ 的值的实际类型是什么?啊,它是 TypeWithString ......现在,如果我们有会发生什么:objectstringd

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值的实际类型,并想象如下代码:

TypeWithString tmpD = (TypeWithString) d;
string tmpO = (string) o; // Actual type is string at execution time
tmpD.MyObject = tmpO;
于 2010-07-01T21:03:19.103 回答
1

您总是可以尝试d.MyString = o as string;which 将 o 转换为(不抛出)字符串,如果不存在转换为 null 。

于 2010-07-01T21:06:34.183 回答