我有如下代码,但它是尴尬。我怎么能更好的结构吗?我必须让我的消费类实现IDisposable,并有条件地构建网络接入等级和处置它时,我做了什么?
protected void ValidateExportDirectoryExists()
{
if (useNetworkAccess)
{
using (new Core.NetworkAccess(username, password, domain))
{
CheckExportDirectoryExists();
}
}
else
{
CheckExportDirectoryExists();
}
}
一种选择,这是有点讨厌,但会工作的基础上,将C#编译器调用Dispose
only if the resource is non-null的事实:
protected void ValidateExportDirectoryExists()
{
using (useNetworkAccess
? new Core.NetworkAccess(username, password, domain)
: null)
{
CheckExportDirectoryExists();
}
}
另一种替代方法是写哪个返回null或NetworkAccess一个静态方法:
private Core.NetworkAccess CreateNetworkAccessIfNecessary()
{
return useNetworkAccess
? new Core.NetworkAccess(username, password, domain)) : null;
}
然后:
protected void ValidateExportDirectoryExists()
{
using (CreateNetworkAccessIfNecessary())
{
CheckExportDirectoryExists();
}
}
同样,我真不知道我不喜欢原来的...这真的取决于你如何往往需要这种模式。
使用您自己的try / finally块,执行类似的逻辑的“使用”,但只有当useNetworkAccess设置做了处置。请注意,如果useNetworkAccess可能被其他线程的影响,你应该复制其价值,并使用该副本都为创建资源和处理它。
如果您在很多方法重复这个模式,你可以打破格局
protected void OptionalNetworkCall(Action action)
{
if (useNetworkAccess)
{
using (new Core.NetworkAccess(username, password, domain))
{
action();
}
}
else
{
action();
}
}
protected void ValidateExportDirectoryExists()
{
OptionalNetworkCall(CheckExportDirectoryExists);
}
using语句是一种捷径,以避免“最后”块,当它使代码更易于理解,才应使用。在你的情况我会写下面的代码。它可能不会像其他一些版本的简短,但更直截了当。
protected void ValidateExportDirectoryExists()
{
Core.NetworkAccess access = useNetworkAccess ? new Core.NetworkAccess(username, password, domain) : null;
try
{
CheckExportDirectoryExists()
}
finally
{
if (access != null)
{
access.Dispose();
}
}
}
protected void ValidateExportDirectoryExists()
{
var access = useNetworkAccess
? new Core.NetworkAccess(username, password, domain)
: null;
using (access)
{
CheckExportDirectoryExists();
}
}
我不知道这是否是“更好”,但你可以使用空对象模式,并有一个“空”一次性的网络访问对象。事情是这样的:
protected void ValidateExportDirectoryExists()
{
using (GetNetworkAccess(username, password, domain))
{
CheckExportDirectoryExists();
}
}
protected IDisposable GetNetworkAccess(string username, string password, string domain)
{
return useNetworkAccess ? new Core.NetworkAccess(username, password, domain) : new NullNetworkAccess(username, password, domain);
}
internal class NullNetworkAccess : IDisposable
{
internal NullNetworkAccess(string username, string password, string domain)
{
}
public void Dispose()
{
}
}
这可能是为自己好太可爱了。
[编辑]在Jon的回答刚才看到空可以在using语句中使用。我不知道!
使用范围,如果这个类实现IDisposible接口将只处理一个对象,是的,你需要实现Dispose方法。
我想这确实是化妆品的问题,如果代码是如此简单。
我可以想象它怎么可能寻找其他途径,我的投票将是这个版本你现在有。
无论是使用语句内封闭将它称为IDispoable.Dispose
由IDisposable
接口决定。由于在MSDN上看到了using
...
提供了一个方便的语法,确保正确使用IDisposable的对象。
因此,如果你把一个自定义类型的using
语句中应该通过IDisposable
接口进行相应的清理其资源。
通过让类实现IDisposable,使用“使用”的语句时,Dispose方法只调用。否则,您必须显式调用处理。
通常IDisposable的由管理内存消耗垃圾收集器的外部(例如使用非托管代码例如)对象来实现。它提供了一种方法来清理任何消耗的内存。
只要你NetworkAccess类实现了IDisposable,Dispose方法将得到尽快using语句的范围是完整的调用。如果是托管代码,那么没有必要处置。只是让垃圾收集完成其工作。