gpt4 book ai didi

c# - 如何正确处置对象 : injected vs. 拥有

转载 作者:太空狗 更新时间:2023-10-29 20:13:24 26 4
gpt4 key购买 nike

我有一个关于处置对象的问题。

考虑这个IDisposable

public class MyClass : DisposableParentClass
{
private MyProp _prop;

public MyClass(MyProp prop)
{
_prop = prop;
}

public MyClass()
{
_prop = new MyProp();
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
_prop.Dispose();
}

base.Dispose(disposing);
}

}

在第一个构造函数中,MyProp 被注入(inject)。所以 MyClass 不是对象的所有者。但是在第二个构造函数中,MyProp 是在本地创建的。我应该始终处置 MyProp,还是应该先检查它是否被注入(inject)。

public class MyClass : DisposableParentClass
{
private MyProp _prop;
private bool _myPropInjected = false;

public MyClass(MyProp prop)
{
_prop = prop;
_myPropInjected = true;
}

public MyClass()
{
_prop = new MyProp();
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
if (!_myPropInjected) { _prop.Dispose(); }
}

base.Dispose(disposing);
}

}

最佳答案

如果你的类(class)应该处理这两种情况:

  1. 它不是所提供对象的所有者,不应该处置它
  2. 它是创建对象的所有者,它应该处理掉它

那么是的,您需要有一种机制来区分这两种情况。

一个常用的方法(反正对我来说很常用)是使用这样的命名约定:

private MyProp _prop;        
private bool _ownsProp = false;

即。反转标志的含义,但这是细节,您的解决方案很好,是的,您需要有这样的解决方案。


如果您有很多这样的字段,其中每个字段都必须有自己的 bool 字段来处理这个问题,那么创建一个辅助类可能是值得的,比如这个 LINQPad程序演示:

void Main()
{
Injectable i1 = new Injectable();
Injectable i2 = new Injectable(new Injected("A"));
Injectable i3 = new Injectable(new Injected("A"), new Injected("B"));

Debug.WriteLine("dispose a and b");
i1.Dispose();

Debug.WriteLine("dispose b");
i2.Dispose();

Debug.WriteLine("no dispose");
i3.Dispose();
}

public class Injected : IDisposable
{
public Injected(string name) { Name = name; }
public string Name { get; set; }
public void Dispose() { Debug.WriteLine(Name + " disposed"); }
}

public class Injectable : IDisposable
{
private Ownable<Injected> _A;
private Ownable<Injected> _B;

public Injectable(Injected a, Injected b)
{
_A = Ownable.NotOwned(a);
_B = Ownable.NotOwned(b);
}

public Injectable(Injected a)
{
_A = Ownable.NotOwned(a);
_B = Ownable.Owned(new Injected("B"));
}

public Injectable()
{
_A = Ownable.Owned(new Injected("A"));
_B = Ownable.Owned(new Injected("B"));
}

public void Dispose()
{
_A.Dispose();
_B.Dispose();
}
}

public class Ownable<T> : IDisposable
where T : class
{
private readonly T _Instance;
private readonly Action _CleanupAction;

public Ownable(T instance, bool isOwned)
{
_Instance = instance;

if (isOwned)
{
IDisposable disposable = instance as IDisposable;
if (disposable == null)
throw new NotSupportedException("Unable to clean up owned object, does not implement IDisposable");

_CleanupAction = () => disposable.Dispose();
}
}

public Ownable(T instance, Action cleanupAction)
{
_Instance = instance;
_CleanupAction = cleanupAction;
}

public T Instance { get { return _Instance; } }

public void Dispose()
{
if (_CleanupAction != null)
_CleanupAction();
}
}

public static class Ownable
{
public static Ownable<T> Owned<T>(T instance)
where T : class
{
return new Ownable<T>(instance, true);
}

public static Ownable<T> Owned<T>(T instance, Action cleanupAction)
where T : class
{
return new Ownable<T>(instance, cleanupAction);
}

public static Ownable<T> NotOwned<T>(T instance)
where T : class
{
return new Ownable<T>(instance, false);
}
}

关于c# - 如何正确处置对象 : injected vs. 拥有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25618145/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com