代码之家  ›  专栏  ›  技术社区  ›  Rabbi

将对象变量中的字符串赋给动态(C)的字符串属性

  •  4
  • Rabbi  · 技术社区  · 14 年前

    我知道这有一点点,可能不完全可以理解。下面是一个我想做的例子。

    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 是一个 一串 .

    这是DLR中的错误还是缺陷?

    有办法绕过它吗?

    如果我不知道提前的类型。但我知道它符合duck输入法。也就是说,我知道它实现了一个不成文的接口。当一个变量确实是正确的类型时,我是否可以为另一个变量赋值?

    非常感谢

    2 回复  |  直到 8 年前
        1
  •  4
  •   Jon Skeet    14 年前

    不,这是预期的。编译器知道 o object ,因此它记录了“尝试查找名为 MyString 然后尝试分配类型的值 对象 对它而言“—如果有一个隐式的 对象 string ,但没有。请注意,语句中唯一动态的部分是 目标 其中…所以这是唯一被动态处理的位。在执行时,“执行时编译器”会有效地说,“值的实际类型是什么?” d ?啊,它是用字符串打字的…现在,如果我们有:

    TypeWithString tmpD = (TypeWithString) d;
    tmpD.MyObject = o;
    

    …会发生编译时错误。

    如果希望它在值中也动态地运行,只需使用 dynamic 而不是 对象 对于指定的值:

    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;
    
        2
  •  1
  •   fbstj    14 年前

    你可以一直尝试 d.MyString = o as string; 如果不存在强制转换,则将强制转换(而不强制转换)为字符串或空值。