2009-11-25 54 views

回答

6

要繼續約翰的回答,而是執行此操作:

string username; 
if (myDic.TryGetValue("username", out username)) 
{ 
    user.Username = username; 
} 
3

你可以在VB中做到這一點,但不是C#。

VB將生成一個臨時變量(在堆棧上),將其地址傳遞給out值,然後在方法調用後對該屬性進行賦值。

一般來說VB是這樣做的,因爲它在整個地方都有很多隱含的東西。這只是它的工作方式。另一方面,C#往往避開隱含性作爲其哲學的一部分。這就是爲什麼,例如,你必須向呼叫站點添加「out」,以便讓參數起作用,並且爲什麼它不支持擴展方法的第一個參數的「ref」參數。

在呼叫站點使用顯式的「out」語法可以在這裏支持屬性。但是,我相信他們不這樣做的原因是因爲VB使用的技巧對於屬性的行爲與對字段的行爲不完全相同。使用字段時,分配會立即發生在方法內發生的地方。如果方法中有其他代碼(通過調用對象的方法)讀取該字段,它將讀取通過輸出參數分配的新字段值。

使用VB技巧的屬性,該屬性直到方法返回後纔會被賦值。這意味着在out參數分配後直接讀取屬性的任何代碼都會讀取舊值。

這裏是什麼,我的意思是一個簡單的例子:)

class C 
{ 
    private int m_bar; 

    public int Bar { get { return m_bar; } set { m_bar = value; }} 

    void foo(out int x) 
    { 
     x = 2; 
     Console.WriteLine(Bar); 
    } 

    void DoStuff() 
    { 
     foo(out m_bar); //outputs 2 
     Bar = 0; 
     //pretend this works 
     foo(out Bar); //outputs 0 
     Console.WriteLine(Bar); // outputs 2 
    } 
} 

內DoStuff(,你會得到不同的行爲,爲第一次調用foo的比你從第二個呼叫爲foo會,雖然大多數人會期望他們以同樣的方式行事。

通常C#試圖避免這些類型的事情。

這是我的猜測,爲什麼他們不支持它(規範只是說不支持,它並不真正說爲什麼)。

相關問題