当变量是IDisposable时,我们会使用using
关键字来管理处理。但是,如果我们在方法中返回值,那么我们应该using
两次吗?
StringContent stringToStringContent(string str)
{
using (StringContent content = new StringContent(str))
{
return content;
}
}
void logStringContent()
{
using (StringContent content = stringToStringContent("test"))
{
Debug.WriteLine(content.ToString());
return;
}
}
在上面的这个例子中,我只有1 new
但我有2 using
同样的事情。所以我觉得它不平衡。是否更好:
a)同时保留using
,语言/编译器知道它的工作以避免双重处置?
b)仅将using
与new
放在一起,在其他情况下则不需要?:
void logStringContent()
{
StringContent content = stringToStringContent("test");
Debug.WriteLine(content.ToString());
return;
}
c)当你不回来时只保留using
,而当你回来时则不需要?:
StringContent stringToStringContent(string str)
{
return new StringContent(str);
}
我唯一能感受到的是b)不是正确答案,因为它不适用于此处描述的问题:.NET HttpClient hangs after several requests (unless Fiddler is active)
答案 0 :(得分:6)
我认为c
在这里是正确的答案 - 你从方法中返回(引用)一个对象 - 在你返回之前已经处理掉了那个对象是没有意义的。例如,File.OpenRead
不会丢弃它返回的流,是吗?
在方法文档中指出调用者负责处理对象是个好主意。同样,一些方法接受一次性类型并声明调用者不应该自己处理该对象。在这两种情况下,都有效地转移了妥善处理对象的责任。
答案 1 :(得分:0)
拥有返回IDisposable
个对象的方法并不是一种不常见的模式,但是在发生异常时防止资源泄漏可能很困难。另一种方法是使用一种方法生成新的IDisposable
接受out
或(如果方法是未密封的和虚拟的)ref
参数,并存储对新对象的引用在那里面。然后,调用者将被问到Dispose
有问题的东西,无论生成它的方法是正常返回还是抛出异常。
否则,如果您希望方法的返回值为新的IDisposable
,并且如果在方法获取资源的时间与返回的时间之间执行任何代码,则应使用类似的方法保护代码:
DisposableThing thingToDispose = null;
try
{
thingToDispose = new DisposableThing(whatever);
// Now do stuff that might throw.
// Once you know you're going to return successfully...
DisposableThing thingToReturn = thingToDispose;
thingToDispose = null;
return thingToReturn;
}
finally
{
if (thingToDispose != null)
thingToDispose.Dispose();
}
请注意,此代码不会“捕获”任何异常,但如果函数通过正确的指定路径退出,则新构造的对象将被释放。请注意,如果此函数抛出异常而不处理新构造的对象,则该对象获取的任何资源都将泄漏,因为调用者将无法处置它。