2015-06-14 86 views
0

我想如果我可以做一個引用,總是指向該特定變量,而不是指向該變量當前表示的對象(或更準確地說是內存位置)。參考變量,而不是對象

舉一個例子,假設我有以下程序,我想創建一個對MyClass a的引用,以便始終返回MyClass a中的任何值,即使該值發生更改。我有一些看起來像的代碼。

class MyClass 
{ 
    public int value = 0; 
} 

class Program 
{ 
    static MyClass saved; //maintained and used by the following two functions 
    static void StoreReference(MyClass input) 
    { 
     saved = input; 
    } 

    static void SetValue() 
    { 
     saved.value = 42; 
    } 

    static void Main(string[] args) 
    { 
     //A couple arbitrary classes I'd like to have references to 
     MyClass a = new MyClass(); 
     MyClass b = new MyClass(); 

     StoreReference(a); 
     a = b; 
     SetValue(); 
     Console.Write(a.value); //should print 42, instead prints 0 since it reads in the original object a was set to 
    } 
} 

是否有任何可以在C#做到這一點,或者任何可以防止被分配給一個新的存儲位置的變量(以使上面的代碼將在返回錯誤= b)的?

+1

,你可以將它定義爲只讀 – dotctor

+0

做你試着做StoreReference(REF MyClass的輸入) –

+0

用只讀的問題是,我希望能夠說a.value中= 42而不是=新MyClass的()因爲第二個示例更改了指向的內存位置。 – user3875080

回答

0

您可以檢查是否saved已經有值與否:

static void StoreReference(MyClass input) 
{ 
    if (saved != null) { 
     return; 
    } 
    saved = input; 
} 
0

我在這裏看到了不少迴應是建議使用一個readonly場或ref參數,但我不知道我完全理解爲什麼這些相關。所以請原諒我,如果我不明白你的問題。

但是從我看到的情況來看,您希望否定作業的效果(a = b;),這是不可能的。

唯一的選擇是切換到您的通話使用saved代替aConsole.Write

static void Main(string[] args) 
{ 
    MyClass a = new MyClass(); 
    MyClass b = new MyClass(); 

    StoreReference(a); 
    a = b; 
    SetValue(); 
    Console.Write(saved.value); 
} 

工作,將打印42喜歡你想要的。但我知道那不是你想要的。

雖然沒有任何語言功能,可以讓代碼編譯讓你做你想做的事。這是一件好事。這就是爲什麼編譯器運行這些檢查(或者它的一部分,無論如何)。如果你忘了你有這個虛構的修飾符來創建一個局部變量只讀,並且你寫出了這個任務,希望它能像任何C語言中的其他任何地方一樣工作,這將是非常混亂的。現在

,到別人一直在說,我真的不知道我明白爲什麼ref又拿出了所有,但readonly:這是一個完全合理的修改,把你的場,它:

  1. 只適用於字段,這意味着它將保護saved但不是局部變量。
  2. 只允許在構造函數中設置值,而不是您要在此處設置的值。

所以,如果你打算使用它,不要誤解我的意思,它對於它做的事很好,請謹慎對待這兩個事實。你需要重新設計。說實話,我會避免在static void Main(...) - 無論如何構造器廢話可能會讓人困惑。

無論如何,我認爲你可能會試圖解決一個本來不應該存在的問題。這可能有助於看到一個真實世界的用例,但是從您給我們的看法來看,這聽起來不像是可能的事情,不幸的是有充分的理由。


對於它的價值,你的標題和開頭段讓我覺得你正在尋找一個指針的指針,這是不是在管理C#允許的。我從來沒有冒險進入非託管C#,但它允許在C++中,所以我懷疑它可能在那裏支持。無論如何,你的問題的其餘部分並沒有真正提醒我,所以這可能不相關。