如果有人有更好的头衔,请告诉我。
我做了一个DisposeHelper而不是这个:
private Something _thing;
void Dispose()
{
if(_thing != null)
{
_thing.Dispose();
_thing = null;
}
}
......我可以这样做:
private Something _thing;
void Dispose()
{
DiposeHelper.Dipose(ref _thing);
}
但显然我不能提供DisposeHelper.Dispose一个IDisposable作为参考,除非我把某些东西作为IDisposable,如下:
private Something _thing;
void Dispose()
{
IDisposable d = _thing;
DiposeHelper.Dipose(ref d);
}
...这意味着它不会使原始字段无效。
这是一个更抽象的例子。 DoThis有效,DoThat没有:
public class Test
{
public Test()
{
Something o = new Something();
DoThis(o);
DoThat(ref o);
}
private void DoThis(IFoo obj) { }
private void DoThat(ref IFoo obj) { }
}
public class Something : IFoo { }
public interface IFoo { }
为什么我不能这样做?
答案 0 :(得分:2)
我不知道为什么你不能的技术原因。
然而,这是有效的:
var o = new Something();
DoThat(ref o);
private void DoThat<T>(ref T obj) where T : class, IFoo {
obj = null;
}
答案 1 :(得分:2)
它不起作用,因为ref
和out
表达式的参数类型必须完全匹配。想象一下,如果DoThat实际上有这个实现:
private void DoThat(ref IFoo obj)
{
obj = new SomeOtherImplementationOfFoo();
}
现在这段代码:
Something o = new Something();
DoThat(ref o);
最终会o
引用SomeOtherImplementationOfFoo
而不是Something
的实例 - 这显然不是正确的。
这就是为什么ref
按照它的方式工作的原因 - 而Rob的答案提供了一种解决方法。
答案 2 :(得分:0)
它不起作用,因为类型必须是属性的确切类型。
想象一下,您可以通过引用将Derived
作为Base
传递给函数。现在,该函数为参数指定一个新对象,该对象为Base
但不是Derived
。 Booom
private Derived d;
void Modify(ref Base b)
{
b=new Base();
}
Modify(ref d);//Booom
解决方法是使用泛型参数,如Rob的回答。
public static void DisposeAndNull<T>(ref T x)
where T:IDisposable
{
x.Dispose();
x=null;
}