2011-06-20 37 views
4

を投げることができたときに、私は次のセットアップ持って廃棄:このケースでは、私は、私はデフォルトを超えるだろう知っているので、私はint.MaxValueを使う理由があるオブジェクト初期化子とプロパティは例外

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

を、しかし、ナンバーワンは決して大規模ではないので、私はその点については大丈夫です。

しかし、私はコード分析Microsoftの基本的な正しさのルールを、それは文句をオンにした場合:

警告2 CA2000:Microsoft.Reliability:メソッド 'においてSomeClass.SomeClass()'、オブジェクトの<を> g_ initLocal0 'はすべての例外パスに沿って配置されていません。オブジェクトへの参照がすべて範囲外になる前に、オブジェクト '<> g _initLocal0'にSystem.IDisposable.Disposeを呼び出します。

それは問題だががPageSizeとSIZELIMITが例外を投げることができるということであり、それはG__initLocal0オブジェクトを発生した場合(_searcherが配置されますない場合でも)に配置されません。これらの例外は、負の数に代入すると例外になりますが、これはここでは起こり得ませんが、それでも文句はあります。

次の例では、オブジェクトインティシアターの外にあるプロパティを通常の割り当てステートメントで設定していますが、ReSharperはInitializerを使用しているはずだと訴えています。私はReSharperを抑制することができましたが、私は抑圧を加えずに仕事を得る方法を見つけ出すのが好きです。

だから私は、私はエラーをキャッチしなければならなかった考え出し、可能ならば、私は私のコンストラクタでキャッチエラーを好きではないので、私はこのようなサーチャーと呼ばれるプロパティを作成:

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

今コード分析し、すべてがあります幸せですが、私は解決策に全く満足していません。

ヒント

+3

あなたのプロパティは、現時点で廃棄された 'DirectorySearcher'を返すでしょう... –

+0

" ...私は私のコンストラクタでキャッチエラーが好きではありません "。何故ですか?あなたは今何をやっているより受け入れられるようです。 –

+0

'SomeClass'は' IDisposable'を実装し、そこにクリーンアップする必要があります。 –

答えて

4

あなたが今行っているやり方は、誰もが幸せになるかもしれないが、あなたは働かないので、あなたを幸せにするかもしれない。 Searcherプロパティに廃棄済みのDirectorySearcherを返送しています。

私はちょうど行いたい:

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ブロックを使用して、間違った私は表示されません。

IDisposableオブジェクトを構築するときに、プロパティの初期化をスローした場合に、あなたが正常にそれらを配置することができないように私は、プロパティの初期化子構文を推薦しません。

+0

あなたとクリスの答えはどちらも、あなたが最初にしているので、私はあなたにそれを与える必要があります良いです。 – carlsb3rg

+0

この一般的な概要はうまくいくようです。 Try/Catchロジックに入れても新しい構文がうまくいかない理由は分かりません。これは非常に微妙な(そして最初は、非常に迷惑)エラーですが、今、私はそれを理解していることを私はFxCopの警告を発行していることをうれしく思います。 –

0

SomeClassインスタンスの全ライフタイム中に_searcherが必要な場合、SomeClassはIDisposableを実装し、Dispose内に_searcherを配置する必要があります。

http://msdn.microsoft.com/de-de/library/system.idisposable.aspxを参照してください。あなたが設定する前に、それが適切にフィールドに割り当てられていることを確認することができるよう

public class SomeClass 
{ 
    private DirectoryEntry _root; 
    private DirectorySearcher _searcher; 

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

    var temp = new DirectorySearcher(_root); 
    temp.PageSize = int.MaxValue; 
    temp.SizeLimit = int.MaxValue; 

    _searcher = temp; 
    } 
} 

あなたは、_searcherの新しいプロパティの初期化子構文を使用しないことで、これを避けることができます。

+0

工assがIDisposableインターを実装して...私は私のコンストラクタに、このコードを移動できますが、問題はまだ同じになります。私は簡潔さのためにそれを含めていない。 – carlsb3rg

6

問題は、コンパイラが効果的に生成されていますプロパティについては、Object initializers in using-block generates code analysis warning CA2000を参照してください。

あり、ここで第二の問題があり、かつHandling IDisposable in failed initializer or constructorを参照してください、_rootまたは_searcherの処分をすることができないので、そこに呼び出し元のコードがSomeClassを処分することはできませんSomeClassの構築中にエラーが発生しているとあればそれはあります。

関連する問題