对象初始化和处置财产时可以抛出异常 [英] Object initializer and Dispose when property can throw exception

查看:127
本文介绍了对象初始化和处置财产时可以抛出异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下设置:

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的原因是因为在这种情况下,我知道我会超过默认值,但数量永远不会大得离谱,所以我很好关于这一点。

The reason I use int.MaxValue is because in this case I know I'll exceed the defaults, but the number will never be ridiculously large, so I'm fine about that point.

但是,如果我打开的代码分析 Microsoft基本正确性规则的它抱怨:

But if I turn on Code Analysis and Microsoft Basic Correctness Rules it complains:

2警告CA2000:Microsoft.Reliability:在方法'SomeClass.SomeClass() '对象'<> G_的 initLocal0'是不是沿着所有的异常路径处理。呼叫System.IDisposable.Dispose的对象。'<>先按g 的_initLocal0'之前对它的所有引用超出范围

Warning 2 CA2000 : Microsoft.Reliability : In method 'SomeClass.SomeClass()', object '<>g_initLocal0' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '<>g_initLocal0' before all references to it are out of scope.

它的问题是,每页和的sizeLimit可以抛出异常,如果发生在 G__initLocal0 对象没有得到处理(即使 _searcher 并获得释放)。他们可以抛出唯一的例外是,如果你将它们分配给一个负数,不能在这里发生,但它仍然抱怨。

It's problem is that PageSize and SizeLimit can throw exceptions, and if that happens the G__initLocal0 object doesn't get disposed (even if _searcher does get disposed). The exception they can throw is if you assign them to a negative number, which can't happen here but it still complains.

接下来,我设置对象intitializer之外的属性与常规赋值语句,但随后ReSharper的笙歌告诉我,我应该使用初始化程序。我可以抑制ReSharper的,但我喜欢图把事情不增加抑制工作的一种方式。

Next I set the properties outside an object intitializer with regular assignment statements, but then ReSharper complains telling me that I should be using Initializer. I could suppress ReSharper, but I like to figure a way of getting things to work without adding suppressing.

所以我想我不得不捕获错误,我不就像在我的构造函数如果有可能捕获错误,所以我创建了一个叫做搜索器属性是这样的:

So I figured I had to catch the error and I don't like catch errors in my constructors if possible, so I created a property called Searcher like this:

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;
  }
}

现在代码分析,一切都是幸福的,但我不是很满意的解决方案可言。

Now Code Analysis and everything is happy, but I'm not happy with the solution at all.

任何提示?

推荐答案

你正在做的事情现在可能让所有人都满意的方式,但你作为它不会工作。在返回处置的DirectorySearcher 搜索器属性。

The way you are doing things now might make everyone happy but you as it wont work. You are returning a disposed DirectorySearcher in your Searcher property.

我只是做的:

public SomeClass()
{
    _root = new DirectoryEntry("ldap://bla");

    try
    {
        _searcher = new DirectorySearcher(_root);
        _searcher.PageSize = 1000;
        _searcher.SizeLimit = 1000;
    }
    catch
    {
         if (_searcher != null)
         {
             _searcher.Dispose();
         }

         throw;
    }



}

}

我看不出什么错在构造函数使用的try-catch 块。

I don't see whats wrong in using try-catch blocks in constructors.

我不推荐的构建的IDisposable 对象,如果一个属性初始化抛出无法处理它们通常是当财产初始化语法。

I wouldn't recommed the property initializer syntax when constructing IDisposable objects as you cannot dispose them normally if a property initialization throws.

这篇关于对象初始化和处置财产时可以抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆