C# reference member variable

前端 未结 5 610
情深已故
情深已故 2021-01-17 23:26

In C#, is there a way to keep a reference as a member variable in an object (like an object pointer in C++), not just as a parameter?

EDIT: How can I make a p

相关标签:
5条回答
  • 2021-01-17 23:43

    No. Don't forget that the argument could reference a local variable which is out of scope by the time you use the object later on. A couple of options:

    • Use a mutable wrapper type
    • Use a delegate which captures the variable instead
    • Redesign your code to not require this in the first place

    It's hard to know which is most suitable without knowing more about what you're trying to achieve, but ref is a dead-end.

    0 讨论(0)
  • 2021-01-17 23:48

    Yes if it is a reference-type instance. And then it is the only way to store it in another class:

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

    No if it's about a value-type, or a reference to a reference.

    You would see simple object-references everywhere that C++ uses pointers, like in building Trees or Linked-Lists.

    class Element { ...; private Element _next; }
    
    0 讨论(0)
  • 2021-01-17 23:54

    If you mean ref the argument passing convention, then no, you cannot store this. From the first note on MSDN:

    Do not confuse the concept of passing by reference with the concept of reference types. The two concepts are not the same...


    Edit: based on your updated question, C# has different nomenclature about pointers and references. A pointer in C# is an unsafe construct used to somewhat directly reference the memory location of an object. I say somewhat because the memory location can change based on garbage collection (unless you fix it in memory).

    References in C# are the default way reference types are passed and stored. They are akin to pointers in other languages, but not quite the same. However, the by-reference argument passing convention allows you to directly change what an object refers to.

    If your objective is to keep a mutable reference to a non-reference type local variable, you'll have to encapsulate the local variable in a reference type (like a class). If you could give some sample code, we can give some specific examples.

    0 讨论(0)
  • 2021-01-17 23:58

    For what its worth, you could use an array of size 1 as a reference/pointer. This yields more readable code than creating a new class to wrap a single value type member.

    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; }
        }
    }
    

    A similar trick can be used to attempt the highly discouraged practice of using mutable structs.

    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; }
        }
    }
    

    Then use array notation to "dereference" it.

    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
    
    0 讨论(0)
  • 2021-01-18 00:00

    The way to get the address of a variable is the & operator, similar to C++. Again similarly to C++, you can store the address as a pointer:

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

    Note that any code that uses the address-of operator (&) or pointers must be within a method marked unsafe or within an unsafe code block. This could be useful if you want to increase performance by not doing array bound-checking for example. The downside (besides safety considerations) is that the assembly must be fully-trusted for it to execute.

    As pointed out, in C#, you very rarely actually store pointers, instead you store references so the garbage collector can operate properly. Ensure that you really need pointers in your code before using them!

    For more info, see: http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx

    0 讨论(0)
提交回复
热议问题