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
.