Replace object instance with another in C#

后端 未结 4 1058
长情又很酷
长情又很酷 2021-02-13 05:17

In this question I would like to find out if and how this is possible. This technique would seem extremely bad practice but it seems that the API (UnityEditor) that I am using,

相关标签:
4条回答
  • 2021-02-13 05:57

    No, that's not possible.

    To actually change all references to an object, you would have to freeze all threads in the process, and access their register sets and stack. That's what the garbage collector does, but it's not possible for regular code.

    What the method most likely does is to make a deep copy of one object onto the other.

    0 讨论(0)
  • 2021-02-13 05:57

    If it is a custom Class you want to reference, i think you can have all the references point to a Fake Reference...

    1. create your class (A)
    2. create your class Interface (IA)
    3. Create a wrapper class based on your interface which just passes all calls to a contained object (AC)

    I Added a Assignment operator so i have all A Objects as ACs.

    class AC:IA  
    {  
        IA ref;  
        AC(IA ref)  
        {  
            this.ref = ref;  
        }  
    
        public void ChangeReference(IA newRef) { ref = newRef;}  
        public static operator = (IA assignedObj)  
        {  
            return (assignedObject is AC) ? assignedObject : new AC(assignedObj);
        }
    
        // implementation of all methods in A
        public override string ToString() { return ref.ToString(); }  
            ...  
    }
    

    Now if you want, you can use the ChangeReference method to switch all to the new Reference..

    in C++ you would use Reference to Reference

    Best of luck

    0 讨论(0)
  • 2021-02-13 06:09

    You could do that if you embed your object into another one that is used to access the object.

    class ObjectReference<T>
       where T : new()
    {
        private T _obj = new T();
    
        public void CreateNewObject()
        {
            _obj = new T();
        }
    
        public T Value { get return _obj; }
    }
    

    Now you can create multiple references to an object of type ObjectReference and only change the local object. The "real" object would be accessed through the Value property

    A slightly different approach is that you create a wrapper that implements the same interface as your "real" object, thus making this wrapping transparent.

    interface ISomeInterface
    {
        string PropertyA { get; set }
        void MethodB (int x);
    }
    
    class TheRealObject : ISomeInterface
    {
        public string PropertyA { get; set }
    
        public void MethodB (int x)
        {
            Console.WriteLine(x);
        }
    }
    
    class Wrapper : ISomeInterface
    {
        TheRealObject _obj = new TheRealObject();
    
        public string PropertyA
        { 
            get { return _obj.PropertyA; }
            set { _obj.PropertyA = value; }
        }
    
        public void MethodB (int x)
        {
            _obj.MethodB(x);
        }
    
        public void CreateNewObject()
        {
            _obj = new TheRealObject();
        }
    }
    

    Now the wrapper can be used as if it was the "real" object. You could also pass an initial instance of the "real" object in the wrapper's constructor and remove the initializer of _obj.

    0 讨论(0)
  • 2021-02-13 06:12

    Since an object state is defined by field values, you can copy memory, containing field values, from one object to another, effectively "replacing" it:

    public static void Replace<T>(T x, T y)
        where T : class
    {
        // replaces 'x' with 'y'
        if(x == null) throw new ArgumentNullException("x");
        if(y == null) throw new ArgumentNullException("y");
    
        var size = Marshal.SizeOf(typeof(T));
        var ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(y, ptr, false);
        Marshal.PtrToStructure(ptr, x);
        Marshal.FreeHGlobal(ptr);
    }
    

    Note that this code requires [StructLayout(LayoutKind.Sequential)] (or LayoutKind.Explicit) attribute defined for a class.

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