2011-06-06 80 views
2

在C#中,是否有一種方法可以將引用保留爲對象中的成員變量(如C++中的對象指針),而不僅僅是作爲參數?C#引用成員變量

編輯:我如何使一個指針或對象作爲成員變量的引用?

+2

你必須詳細說明,你的意思'ref'或只是通俗的 「參考」? – user7116 2011-06-06 14:31:48

+2

作爲對象成員的對象實際上是。它已經在作爲參考。你不需要額外的東西。如果你想到生命週期控制。然後,垃圾收集器將在最後一次引用被釋放時關注銷燬該對象。 – 2011-06-06 14:31:53

回答

3

如果你的意思是ref the argument passing convention,那麼你不能存儲這個。從MSDN上的第一個註釋:

不要混淆引用傳遞的概念與引用類型的概念。這兩個概念是不一樣的......


編輯:根據您的更新問題,C#有大約指針和引用不同的術語。 A pointer in C# is an unsafe construct用於有點直接引用對象的內存位置。我之所以這麼說,是因爲內存位置可以基於垃圾收集進行更改(除非將其修復在內存中)。

References in C# are the default way reference types are passed and stored。他們類似指針在其他語言,但不完全相同。但是,參數傳遞約定允許您直接更改對象引用的內容。

如果您的目標是將可變引用保留爲非引用類型局部變量,則必須將局部變量封裝在reference type (like a class)中。如果你可以給出一些示例代碼,我們可以給出一些具體的例子。

10

不可以。不要忘記,參數可能會引用一個局部變量,這個變量在您稍後使用該對象時超出了範圍。一對夫婦的選擇:

  • 使用可變的包裝類型
  • 使用捕獲變量的委託,而不是
  • 重新設計你的代碼在首位不需要此

很難知道哪一個是最適合的,而不知道你想要達成什麼,但ref是一個死衚衕。

3

是的,如果它是一個引用類型的實例。然後是將其存儲在另一個類的唯一方法:

class Bar { } 

class Foo 
{ 
    private Bar b; // b is a reference to a Bar 
} 

沒有,如果它是關於一個值類型,或者引用的參考。

您會在C++使用指針的任何地方看到簡單的對象引用,例如在構建樹或鏈接列表中。

class Element { ...; private Element _next; } 
1

獲取變量地址的方法是&運算符,與C++類似。再次類似於C++,可以將地址存儲作爲指針:

class Foo 
{ 
    object* _objPtr; 

    Foo(object obj) 
    { 
     unsafe 
     { 
      _objPtr = &obj; 
     } 
    } 
} 

注意,使用該地址的運營商(&)或指針的任何代碼必須在一個方法標記爲不安全或不安全的代碼塊中。 如果您想通過不做數組邊界檢查來提高性能,這可能會很有用。不足之處(除了安全考慮因素)是程序集必須完全信任才能執行。

如前所述,在C#中,您很少實際存儲指針,而是存儲引用,以便垃圾收集器可以正常運行。在使用它們之前,確保你的代碼中真的需要指針!

欲瞭解更多信息,請參見:http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx

+1

技術上正確但不好的建議,完全沒有必要。 – 2011-06-06 14:58:42

+0

他的問題是沒有任何語境的一行 - 「我怎樣才能做出指針?」你是對的,幾乎總是不必要的,但也許在他看來這是適當的。 – Greggo 2011-06-06 15:43:08

+1

「而不是你存儲引用,所以垃圾收集器可以正常運行」< - 聽起來比使用指針更安全。我該怎麼做? – Andrew 2011-06-06 15:55:29

1

爲了什麼它的價值,你可以使用大小爲1的數組作爲參考/指針。這產生比創建一個新類來包裝單個值類型成員更可讀的代碼。

public struct StructWithReferenceMember 
{ 
    private int[] intStoredAsReference; 

    public StructWithReferenceMember(int asValue, int asReference) 
     : this() 
    { 
     IntStoredAsValue = asValue; 
     intStoredAsReference = new int[] { asReference }; 
    } 

    public int IntStoredAsValue { get; set; } 
    public int IntStoredAsReference 
    { 
     get { return intStoredAsReference[0]; } 
     set { intStoredAsReference[0] = value; } 
    } 
} 

一個類似的技巧可以用來嘗試使用可變結構的高度鼓舞人心的做法。

public class ReferenceProperty<T> 
{ 
    private T[] typeReference; 

    public ReferenceProperty(T value) 
    { 
     typeReference = new T[] { value }; 
    } 

    public T PropertyAsValue 
    { 
     get { return typeReference[0]; } 
     set { typeReference[0] = value; } 
    } 
    public T[] PropertyAsReference 
    { 
     get { return typeReference; } 
    } 
} 

然後使用數組符號來「解引用」它。

public struct MutableStruct 
{ 
    public int member; 

    public MutableStruct(int value) 
    { 
     member = value; 
    } 
} 
     ReferenceProperty<MutableStruct> referenceToValueType = new ReferenceProperty<MutableStruct>(new MutableStruct(3)); 
     Console.WriteLine("original value: " + referenceToValueType.PropertyAsValue.member.ToString()); 

     //referenceToValueType.PropertyAsValue.member = 4; // compiler error - cannot modify return value because it is not a variable 
     MutableStruct copyOfStruct = referenceToValueType.PropertyAsReference[0]; // or referenceToValueType.PropertyAsValue 
     copyOfStruct.member = 4; 
     Console.WriteLine("original value after modifying copy: " + referenceToValueType.PropertyAsValue.member.ToString()); 

     referenceToValueType.PropertyAsReference[0].member = 5; 
     Console.WriteLine("original value after modifying reference: " + referenceToValueType.PropertyAsValue.member.ToString()); 

original value: 3 
original value after modifying copy: 3 
original value after modifying reference: 5