2

いくつかの基になるネイティブ リソースを使用するオブジェクトがあり、次のインスタンスへのポインターがあり、次のように反復します。

MyObject begin = null;

try
{
    begin = GetFirst();

    while (begin != null)
    {
        MyObject next = begin.Next();
        // do something with begin
        begin.Dispose();
        begin = next;
    }
}
finally
{    
    if (begin != null)
    {
        begin.Dispose();
    }
}

コード分​​析の問題が発生します。

CA2202: Microsoft.Usage: オブジェクト 'begin' はメソッド 'x()' で複数回破棄できます。System.ObjectDisposedException の生成を回避するには、オブジェクトに対して Dispose を複数回呼び出さないでください。

このエラーを抑制せずに取り除く方法はありますか?

4

3 に答える 3

4

確かに、最後のコードブロックは不要のようです。もしそうならbegin != null、あなたのwhileループは続くべきでしたね?

更新begin:例外がスローされた場合に備えて、最後に取得した値が確実に破棄されるようにしようとしているようです。これを試して:

MyObject begin = GetFirst();

while (begin != null)
{
    MyObject next;
    using (begin)
    {
        next = begin.Next();
        // do something with begin
    }

    begin = next;
}

上記の提案では、実際には、ブロックnextの終わりの前に、に割り当てられた最後の値である、破棄されていないオブジェクトが発生する可能性があることに注意してください。usingこのシナリオは元の質問ではカバーされていなかったため、上記の提案では取り上げていません。ただし、それが潜在的な問題である場合は、検討する必要があります。

于 2010-09-01T23:33:52.667 に答える
0

コード分​​析では、Dispose()メソッド中に例外が発生する可能性があると見なされているようです。その場合は、nullではないがすでに破棄されているへの参照を使用してfinallyブロックに入りますbegin

begin.Dispose()追加のエラートラップと処理でへの呼び出しをラップすることを計画している場合にのみ、@Danのこのアプローチを好むことに注意してください。IMO、ダンのソリューションはよりエレガントです。

警告を削除するtry-finallyアプローチは次のとおりです。

MyObject begin = GetFirst();
MyObject next = null;

while (begin != null)
{
    try
    {
        next = begin.Next();
        // do something with begin
    }
    finally
    {
        begin.Dispose();
        begin = next;
    }
}
于 2010-09-02T00:19:33.433 に答える
0

明らかに、チェーン内の最初のアイテムを識別するための何らかのメカニズムがありますか?おそらく、最初のアイテムを格納している他のオブジェクトまたは静的なものですか?

もともとdisposeを呼び出しているコードではどうですか:

GetFirst().Dispose();

次に、破棄メソッドの唯一の責任は、現在のアイテムとその子を破棄することです。

public void Dispose()
{
    if (Next() != null)
    {
        Next().Dispose();
    }
}

これにより、dispose メソッド内でループする必要がなくなります。Disposeパターンも見てみましょう

于 2010-09-02T00:28:07.687 に答える