我有以下代码,但很尴尬。我怎么能更好地构建它?我是否必须使我的消费类实现IDisposable并有条件地构建网络访问类并在完成后处置它?
protected void ValidateExportDirectoryExists()
{
if (useNetworkAccess)
{
using (new Core.NetworkAccess(username, password, domain))
{
CheckExportDirectoryExists();
}
}
else
{
CheckExportDirectoryExists();
}
}
答案 0 :(得分:58)
基于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();
}
}
同样,我仍然不确定我不喜欢原版......这实际上取决于你需要这种模式的频率。
答案 1 :(得分:7)
如果你在许多方法中重复这种模式,你可以打破模式
protected void OptionalNetworkCall(Action action)
{
if (useNetworkAccess)
{
using (new Core.NetworkAccess(username, password, domain))
{
action();
}
}
else
{
action();
}
}
protected void ValidateExportDirectoryExists()
{
OptionalNetworkCall(CheckExportDirectoryExists);
}
答案 2 :(得分:4)
using语句是避免“finally”块的快捷方式,只有在使代码更容易理解时才能使用。在你的情况下,我会写下面的代码。它可能不像其他一些版本那么简短,但更为直接。
protected void ValidateExportDirectoryExists()
{
Core.NetworkAccess access = useNetworkAccess ? new Core.NetworkAccess(username, password, domain) : null;
try
{
CheckExportDirectoryExists()
}
finally
{
if (access != null)
{
access.Dispose();
}
}
}
答案 3 :(得分:2)
protected void ValidateExportDirectoryExists()
{
var access = useNetworkAccess
? new Core.NetworkAccess(username, password, domain)
: null;
using (access)
{
CheckExportDirectoryExists();
}
}
答案 4 :(得分:1)
我不知道它是否“更好”,但你可以使用null对象模式并拥有一个“null”一次性网络访问对象。像这样:
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的回答中看到null可以在using语句中使用。我不知道!
答案 5 :(得分:0)
使用scope只会在类实现IDisposible接口时处理一个对象,所以是的,你需要实现dispose方法。
答案 6 :(得分:0)
如果代码简单,我想这真的是化妆品问题。
我可以想象它是如何看待另一种方式,我的投票将是你现在拥有的这个版本。
答案 7 :(得分:0)
无论using语句中包含什么内容,IDispoable.Dispose
接口都会调用它IDisposable
。正如MSDN上using
...
提供方便的语法 确保正确使用IDisposable 对象。
因此,如果您在using
语句中放置自定义类型,则应通过IDisposable
接口正确清理其资源。
答案 8 :(得分:0)
通过让您的类实现IDisposable,只有在使用“using”语句时才会调用dispose方法。否则你必须明确地调用dispose。
通常,IDisposable由管理垃圾收集器之外的内存消耗的对象实现(例如,使用非托管代码)。它提供了一种清理任何消耗内存的方法。
只要您的NetworkAccess类实现了IDisposable,就会在using语句的范围完成后立即调用dispose方法。如果是托管代码,则无需处理它。让垃圾收集器完成它的工作。
答案 9 :(得分:0)
使用您自己的try / finally块,它执行与'using'类似的逻辑,但只有在设置了useNetworkAccess时才执行dispose。请注意,如果useNetworkAccess可能受到其他线程的影响,则应复制其值并使用该副本创建资源并进行处置。