C#引用成员变量

时间:2011-06-06 14:30:24

标签: c# pointers reference

在C#中,有没有办法将引用作为成员变量保存在对象中(比如C ++中的对象指针),而不仅仅是作为参数?

编辑:如何将对象的指针或引用作为成员变量?

5 个答案:

答案 0 :(得分:12)

没有。不要忘记,参数可以引用一个局部变量,该变量在您稍后使用该对象时超出范围。有两种选择:

  • 使用可变包装类型
  • 使用代替
  • 捕获变量的代理
  • 重新设计您的代码,首先不要求这样做

如果不了解更多关于你想要达到的目标,很难知道哪个是最合适的,但ref是一个死胡同。

答案 1 :(得分:4)

如果你的意思是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。它们类似于其他语言中的指针,但不完全相同。但是, by-reference 参数传递约定允许您直接更改对象引用的内容。

如果您的目标是将可变引用保留到非引用类型的局部变量,则必须将局部变量封装在reference type (like a class)中。如果您可以提供一些示例代码,我们可以提供一些具体示例。

答案 2 :(得分:3)

是,如果它是引用类型实例。然后它是将它存储在另一个类中的唯一方法:

class Bar { }

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

否,如果它是关于值类型或对引用的引用。

你会看到C ++使用指针的所有地方的简单对象引用,比如构建树或链接列表。

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

答案 3 :(得分:2)

为了它的价值,您可以使用大小为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

答案 4 :(得分:1)

获取变量地址的方法是&amp;运算符,类似于C ++。再次类似于C ++,您可以将地址存储为指针:

class Foo
{
    object* _objPtr;

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

请注意,使用地址运算符(&amp;)或指针的任何代码都必须位于标记为不安全的方法内或不安全的代码块中。 如果您想通过不进行数组绑定检查来提高性能,这可能很有用。缺点(除了安全考虑因素)是程序集必须完全受信任才能执行。

正如所指出的,在C#中,你很少存储指针,而是存储引用,以便垃圾收集器可以正常运行。在使用之前确保您的代码中确实需要指针!

有关详细信息,请参阅:http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx