2011-06-06 81 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