2012-07-11 64 views
0

從外部方法更改類屬性已經發生了錯誤,同時嘗試改變分配(「f.StartTime」內線等級, 但如果字符串的屬性設置爲一個字符串變量它的工作,但不改變「開始時間'屬性)使用REF

喜歡:

string x = f.StartTime; 
ChangeText(ref x); // There's no error, but f.StartTime didn't change. 
//Unless: 
f.StartTime = x; 
當然

這是假的方法......

,所以我想執行以下代碼。

public class MainClass 
{ 
    public class Foo 
    { 
     public string StartTime { get; set; } 
     public string ToTime { get; set; } 
    } 

    private void ChangeText(ref string Time) 
    { 
     Time = DateTime.Now.ToString(); 
    } 

    public void SetClassObjects() 
    { 
     Foo f = new Foo() 
     { 
      StartTime = "Any Text", 
      ToTime = "Any Text" 
     }; 

     ChangeText(ref f.StartTime); 

     // An error: A property, indexer or dynamic member access may not be passed as an out or ref parameter 
    } 

回答

1

字符串是不可變的,分配給f.StartTimex創建不的參考副本。因此您需要重新分配f.StartTime。該ref包括將正確地重新分配基準x(實際上在x下一個新的串點),而是參考f.StartTime丟失,由於字符串的值類型語義。請注意,字符串是引用類型,它們只是遵循值類型的語義。

我會從提供string在這種情況下一個ref迴避,而是做這樣的事情:

f.StartTime = GetText(); 

private string GetText() 
{ 
    return DateTime.Now.ToString(); 
} 

或可選擇地通過FooChangeText方法:

private void ChangeText(Foo fooItem) 
{ 
    fooItem.Time = DateTime.Now.ToString(); 
} 

然後,只需ChangeText(f);

如果你想爲變異屬性字符串的通用機制,你可以有一個接口:

public interface ICanHaveMyTextChanged 
{ 
    void ChangeText(string newText); 
} 

其中Foo工具:

class Foo : ICanHaveMyTextChanged 
{ 
    public string StartTime { get; private set; } 

    public void ChangeText(string newText) 
    { 
     StartTime = newText; 
    } 
} 

,然後指定接口的參數而不是Foo

private void ChangeText(ICanHaveMyTextChanged item) 
{ 
    item.ChangeText(DateTime.Now.ToString()); 
} 

並致電:

var f = new Foo(); 
ChangeText(f); 

現在任何實現此接口的類都可以讓它的文本發生更改。

+0

謝謝主席先生,我知道這一點,但我想概括在一個大的類此方法來更改一個字符串值,而不是(僅Foo類)。 – 2012-07-11 10:57:25

+0

@HadyShaltout我用一個更一般的版本使用接口更新了我的答案,但如果你想要我的意見,堅持解決方案,你返回一個字符串,而不是試圖改變一個。 – 2012-07-11 11:01:44