2011-09-06 46 views
3

說我有一個簡單的類是這樣的:使用ref關鍵字保存,以便以後使用對象引用

public class ReferenceChanger<T> 
{ 
    public T SavedElement { get; private set; } 

    public ReferenceChanger(T elementToSave) 
    { 
     SavedElement = elementToSave; 
    } 

    // This method would change the original variable (given as a constructor argument) 
    public void SetNewReference(T newElement) 
    { 
     SavedElement = newElement; 
    } 
} 

本級的撲救給它的構造元素,無論元素是。然而,「SavedElement」(它的後臺字段)是對實例創建時給定的對象的引用。

有沒有辦法保存參考變量(如使用ref關鍵字),因此,如果原始項目傳遞給構造變化,SavedElement會自動反映這種變化,彷彿該對象已通過ref關鍵字? (即使我使用裁判關鍵字,我將無法保存參考的方式。)

更新,使其意圖更清晰:

public class ExampleClass 
{ 
    public List<int> Numbers { get; set; } 
} 

public static void Main() 
{ 
    ExampleClass temp = new ExampleClass(); 
    temp.Numbers = new List<int>() { 1, 2, 3 }; 

    ReferenceChanger<List<int>> changer = new ReferenceChanger<List<int>>(temp.Numbers); 
    // Here, a reference to the List<int> instance (containing 1,2,3) is stored in changer's SavedElement 

    // Then I do this: 
    changer.SetNewReference(new List<int>() { 5, 6, 7 }); 

    // Now, only changer's SavedElement was changed, but temp's property Numbers was not changed. 
    // Is there a way to change the temp's property Numbers from the changer? 
} 
+1

看到類是自動引用類型,傳遞給你的ctor的對象中的變化應該反映在你的SavedElement中,因爲它只是引用該對象,它不是通過值傳遞,而是通過引用。 –

+0

您是否想要在調用'SetNewReference'之前需要使用'SavedElement'的代碼來隨後對新版本的'SavedElement'執行操作? – Reddog

+0

如果是這樣,只需將整個ReferenceChanger實例傳遞給該操作,並在需要時調用SavedElement。它將始終使用「最新」參考。 – Reddog

回答

4

聽起來像是您在尋找TypedReference__makeref關鍵字。

警告:它們記錄不準確,不在C#的標準化部分。

有一個在this question.

+0

有趣的閱讀。 –

0

在C#中的所有類是引用對象,所以你已經編碼應該更新值SavedElement。但是,如果T是原始類型(例如,int,string等),則這將不起作用,因爲它們是按值設置的。你需要在T上設置一個約束來確保它是一個類。

+0

一個輕微的更正 - 字符串是一個引用類型,它恰好是一個不可變的引用類型。您可以有兩個字符串變量指向完全相同的字符串實例。 –

0

了很多信息無法正常地捕捉到一個變量的引用,並存儲爲一個屬性。一個駭人聽聞的解決方案(並不真正表明這是一個好主意,我會首先探索其他途徑)是將其捕獲到關閉中並通過關閉。閉包捕獲變量,而不是值。因此,其他地方可以觀察到變量的變化。例如,給定

class Foo 
{ 
    public int Baz { get; set; } 
} 

class Bar 
{ 
    private Func<Foo> fooGetter; 

    public Bar(Func<Foo> fooGetter) 
    { 
     this.fooGetter = fooGetter; 
    } 

    public void Do() 
    { 
     Console.WriteLine(fooGetter().Baz); 
    } 
} 

你可以有

Foo foo = new Foo() { Baz = 1 }; 
Bar bar = new Bar(() => foo); 
bar.Do(); 
foo = new Foo() { Baz = 2 }; 
bar.Do(); 

更改變量foo觀察,因爲這是呼叫者封閉在拉姆達。如果來電者簡單地說() => new Foo(),你當然不會觀察到任何變化。

相關問題