2010-07-01 66 views
3

我知道它有點含義,可能不完全可以理解。所以這裏是我想要做的一個例子。將對象變量中保存的字符串賦給動態字符串屬性(C#)

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'。 儘管MyStringstring類型,並且o中保存的是string

這是DLR中的缺陷還是缺點?

有沒有辦法避開它?

如果我不知道類型提前。但我知道它符合鴨子打字。即我知道它實現了一個不成文的界面。無論如何,當他們真的是正確的類型時,我可以將一個變量分配給另一個變量嗎?

非常感謝你

回答

4

不,這是預期的。編譯器知道o的類型爲object,因此它會記錄一個動態操作「試圖找到名爲MyString的屬性,然後嘗試爲其分配值object」 - 它可以這樣做,如果存在隱式轉換objectstring,但沒有。請注意,您聲明中唯一動態的部分是它的目標 ......所以這是唯一被動態處理的位。 ?在執行時,「執行即時編譯器」將有效地說,「什麼是實際類型的d值啊,它的TypeWithString ......現在,如果我們有會發生什麼:

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; 

這一次,「執行時間編譯器」會要求自己的實際類型都do價值的,試想這樣的代碼:

TypeWithString tmpD = (TypeWithString) d; 
string tmpO = (string) o; // Actual type is string at execution time 
tmpD.MyObject = tmpO; 
1

你總是可以嘗試d.MyString = o as string;,將投(沒有出現)O到一個字符串或null如果演員不存在。

+0

B「H 我不知道它將會發生什麼,否則我會將它存儲在正確的變量中。 – Rabbi 2010-07-04 02:04:13