C#引用成员变量

本文关键字:变量 成员 引用 | 更新日期: 2023-09-27 17:58:41

在C#中,有没有一种方法可以将引用作为对象中的成员变量(就像C++中的对象指针一样),而不仅仅是参数

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

C#引用成员变量

否。不要忘记,当您稍后使用该对象时,该参数可能会引用一个超出范围的局部变量

  • 使用可变包装器类型
  • 请改用捕获变量的委托
  • 重新设计代码,使其一开始就不需要

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

如果你指的是传递约定的参数ref,那么不,你不能存储它。来自MSDN上的第一条注释:

不要混淆引用传递的概念和引用类型的概念。这两个概念不一样。。。


编辑:根据您更新的问题,C#对指针和引用有不同的命名法。C#中的指针是一个不安全的构造,用于在某种程度上直接引用对象的内存位置。我之所以这么说,是因为内存位置可能会根据垃圾收集而更改(除非您在内存中修复它)。

C#中的引用是传递和存储引用类型的默认方式。它们类似于其他语言中的指针,但并不完全相同。但是,by-reference参数传递约定允许您直接更改对象所指的内容。

如果您的目标是保持对非引用类型局部变量的可变引用,则必须将该局部变量封装在引用类型(如类)中。如果你能给出一些示例代码,我们可以给出一些具体的例子。

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

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

如果是关于值类型或对引用的引用,则为否

您会在C++使用指针的任何地方看到简单的对象引用,比如在构建树或链表中。

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

就其价值而言,您可以使用大小为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

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

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

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

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

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