c# -当一个变量被赋值给另一个变量(复制构造函数?)时,有没有办法做一些工作?

本文关键字:变量 工作 有没有 构造函数 一个 另一个 赋值 复制 | 更新日期: 2023-09-27 17:52:37

var abc = new MyObject();
var xyz = abc;

就我的理解,xyz和abc是不同的对象,指向相同的信息。

有办法我可以做refcounting吗?基本上,我想在对象内部增加一个值,当赋值发生

c# -当一个变量被赋值给另一个变量(复制构造函数?)时,有没有办法做一些工作?

No。c#不是c++;在您粘贴的代码片段中,该值实际上并没有被复制(除非MyObject是一个值类型)。

不,xyzabc是不同的引用相同的对象。

不,你不能做引用计数

做到这一点的唯一方法是利用(隐式)强制转换操作符重载。这可能不是Eric等人的本意,但如果您为此精心设计了类,它就会起作用。

在重载操作符中,可以创建new(左侧)对象并更新任何引用计数器。然而,很明显,这意味着要确保没有其他方法可以绕过该方案。也就是说,右边的对象必须始终是正确的类型。而使用var则是完全不可能的。

c#不允许重载赋值操作符。您可以使用增加/减少引用计数的包装器,但这并不美观。这里是一个粗略的草图:

class RefCounted<T>
{
    private int refCount;
    public readonly T Obj;
    public RefCounted(T obj)
    {
        Obj = obj;
    }
    public void Get()
    {
        refCount++;
    }
    public void Release()
    {
        if (refCount > 0)
        {
            refCount--;
        }
    }
}
class Wrapper<T> : IDisposable
{
    private RefCounted<T> obj;
    private bool disposed = false;
    public Wrapper(RefCounted<T> o)
    {
        o.Get();
        obj = o;
    }
    public Wrapper<T> Copy()
    {
        return new Wrapper<T>(obj);
    }
    public static implicit operator T(Wrapper<T> wrapper)
    {
        return wrapper.obj.Obj;
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    private void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                obj.Release();
                obj = null;
            }
            disposed = true;
        }
    }
}
static class Wrapper
{
    public static Wrapper<T> New<T>(T obj)
    {
        return new Wrapper<T>(new RefCounted<T>(obj));
    }
}

下面是一个例子:

public class Task
{
    public int TaskId { get; set; }
    public int ParentId { get; set; }
}
...
var o = Wrapper.New(new Task() { TaskId = 1 });
var o1 = o.Copy();
var o2 = o1.Copy();
((Task) o1).TaskId = 3;
o2.Dispose();
o1.Dispose();
o.Dispose();

由于包装器实现了IDisposable,因此您也可以使用using来确定作用域。