【发布时间】:2011-06-20 10:37:15
【问题描述】:
我有以下设置:
public class SomeClass
{
private DirectoryEntry _root;
private DirectorySearcher _searcher;
public SomeClass()
{
_root = new DirectoryEntry("ldap://bla");
_searcher = new DirectorySearcher(_root)
{
PageSize = int.MaxValue,
SizeLimit = int.MaxValue
}
}
}
我使用 int.MaxValue 的原因是因为在这种情况下我知道我会超过默认值,但这个数字永远不会大得离谱,所以我对这一点很好。
但如果我打开 代码分析 和 Microsoft 基本正确性规则,它会抱怨:
警告 2 CA2000:Microsoft.Reliability:在方法“SomeClass.SomeClass()”中,对象“g_initLocal0”并未沿所有异常路径进行处理。在对对象“g_initLocal0”的所有引用超出范围之前调用 System.IDisposable.Dispose。
问题是 PageSize 和 SizeLimit 可以抛出异常,如果发生这种情况,G__initLocal0 对象不会被释放(即使 _searcher 确实被释放)。他们可以抛出的异常是如果您将它们分配给负数,这在这里不会发生,但它仍然会报错。
接下来,我使用常规赋值语句在对象初始化器之外设置属性,但是 ReSharper 抱怨告诉我应该使用初始化器。我可以抑制 ReSharper,但我喜欢想办法在不添加抑制的情况下让事情正常工作。
所以我认为我必须捕获错误,如果可能的话,我不喜欢在构造函数中捕获错误,所以我创建了一个名为 Searcher 的属性,如下所示:
private DirectorySearcher _searcher;
public DirectorySearcher Searcher
{
get
{
if (_searcher != null) return _searcher;
var searcher = new DirectorySearcher();
try
{
searcher.PageSize = int.MaxValue;
searcher.SizeLimit = int.MaxValue;
_searcher = searcher;
}
catch
{
searcher.PageSize = 1000;
searcher.SizeLimit = 1000;
}
finally
{
searcher.Dispose();
}
return _searcher;
}
}
现在代码分析和一切都很满意,但我对解决方案一点也不满意。
有什么提示吗?
【问题讨论】:
-
您的财产目前将返回一个已处置的
DirectorySearcher... -
"...我不喜欢在构造函数中捕获错误"。这是为什么?似乎比你现在所做的更容易接受。
-
SomeClass应该实现IDisposable并在那里清理。 -
我看到我正在返回一个已处理的 DirectorySearcher,但该死的东西出于某种原因有效。即使是对 Searcher 的第二次调用也可以正常工作。我可以将此代码移动到我的构造函数,但问题仍然是一样的......
-
“该死的东西出于某种原因工作” -> 我可以确认 DirectorySearcher 违反了所有逻辑,并且在被处理然后调用以进行目录搜索之后不会抛出任何类型的异常。但是你为什么要依赖它呢?您担心 ReSharper 对您的代码所做的纯美学评论,但不担心使用已处置的对象?
标签: c#