C# - 当一个变量被分配给另一个变量时,有什么方法可以做一些工作(复制构造函数?)

发布于 2024-11-02 16:52:49 字数 145 浏览 0 评论 0原文

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

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

有什么办法可以进行参考计数吗?基本上,我想在赋值时增加对象内部的值

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

As I understand it, xyz and abc are distinct objects pointing to the same information.

Is there a way I can do ref counting? Basically, I want to increment a value inside the object, when an assignment happens

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

电影里的梦 2024-11-09 16:52:50

不,C# 不是 C++;C# 不是 C++。该值实际上并未复制到您粘贴的代码片段中(除非 MyObject 是值类型)。

No. C# is not C++; the value isn't actually copied in the code snippet you pasted (unless MyObject is a value type).

寄居者 2024-11-09 16:52:50

不,xyzabc 是对同一对象的不同引用

不,你不能进行引用计数。

No, xyz and abc are distinct references to the same object.

And no, you cannot do reference counting.

笑咖 2024-11-09 16:52:50

做到这一点的唯一方法是利用(隐式)强制转换运算符重载。也许这不是 Eric 等人的意图,但如果你仔细设计你的类,它就会起作用。

在重载运算符中,您可以创建新的(左侧)对象并更新任何引用计数器。然而,很明显,这意味着要确保围绕该方案不存在其他方法。即右侧的对象必须始终是正确的类型。并且使用“var”是完全不可能的。

The only way of doing this is by utilizing (implicit) cast operator overloads. Probably this is not, what was intended by Eric et.all, but it works if you design your classes carefully for it.

In the overloaded operator, you can create the new (left side) object and update any reference counters. However, it is clear, this implies to make sure, no other ways exists around that scheme. I.e. the object on the right side must always be of the correct type. And the use of 'var' would be completely impossible.

失而复得 2024-11-09 16:52:50

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();

您还可以使用 using 来确定范围,因为包装器实现了 IDisposable

C# doesn't allow the overloading of the assignment operator. You could use wrappers that increment/decrement the reference count, but that's not as pretty. Here's a rough sketch:

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

Here's an example:

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();

You can also use using for scoping since the wrapper implements IDisposable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文