0

C# プロジェクトで次のオブジェクト処理コード パターンに気付きましたが、それが受け入れられるかどうか疑問に思っていました (ただし、機能します)。

public object GetData()
{
    object obj;

    try
    {
        obj = new Object();

        // code to populate SortedList

        return obj;
    }
    catch
    {
        return null;
    }
    finally
    {
        if (obj != null)
        {
            obj.Dispose();
            obj = null;
        }
    }
}

この例では、プロジェクトの実際の IDisposable クラスではなく、一般的な「オブジェクト」を使用しています。

値が返された場合でも、「finally」ブロックが毎回実行されることはわかっていますが、オブジェクトが null に設定されているため、何らかの方法で戻り値に影響します (または、新しいオブジェクト インスタンスになります)。オブジェクトの破棄と GC の目的のため)。

更新 1:

次のスニペットを試してみましたが、返されるオブジェクトは null ではありませんが、ローカル オブジェクトは null に設定されているため、動作します。これは、以下のコメントのいくつかを考慮すると少し奇妙です。

public StringBuilder TestDate()
{
    StringBuilder sb;

    try
    {
        sb = new StringBuilder();

        sb.Append(DateTime.UtcNow.ToString());

        return sb;
    }
    catch
    {
        return null;
    }
    finally
    {
        sb = null;
    }
}

ところで、私はC# 4.0を使用しています。

PS私はこのプロジェクトコードを見直しています。私はオリジナルの作者ではありません。

更新 2:

この謎の答えが見つかりました [1]。finally ステートメントは実行されますが、戻り値は影響を受けません (finally ブロックで設定/リセットされた場合)。

[1] try { return x; で実際に起こること } 最後に { x = null; } 声明?

4

4 に答える 4

5

Objectこのコードは正常にコンパイルされますが (実際には を使用しておらず、 を実装するものを使用していると仮定しますIDisposable)、おそらくやりたいことは実行されません。newC# では、 ;なしでは新しいオブジェクトを取得できません。このコードは、既に破棄されたオブジェクトへの参照を返します。オブジェクトと Dispose() が実際に行うことによっては、破棄されたオブジェクトを使用しようとすると、プログラムがクラッシュする場合とクラッシュしない場合があります。

オブジェクトを作成し、それを使って何らかの処理を行い、成功した場合はオブジェクトを返し、失敗した場合は null (およびオブジェクトを破棄) するという考えだと思います。もしそうなら、あなたがすべきことは次のとおりです。

try {
    obj = new MyClass();
    // ... do some stuff with obj
    return obj;
}
catch {
    if(obj != null) obj.Dispose();
    return null;
}
于 2013-09-10T00:57:40.320 に答える
2

ステートメントを使用するだけusingで、それと同じ結果が得られ、標準的な方法です

public int A()
{
    using(IDisposable obj = new MyClass())
    {
        //...
        return something;
    }
}

ただし、IDisposable オブジェクトを返さないことをお勧めします。オブジェクトを処分するとき、それは「使用できない」と見なされるはずです。それで、なぜそれを返すのですか?

オブジェクトの存続期間を methodAの存続期間よりも長くする必要がある場合は、呼び出し元のメソッドBでオブジェクトをインスタンス化し、それをパラメーターとして method に渡すことを検討してくださいA。この場合、 methodはステートメントBを使用するメソッドであり、その中で を呼び出します。usingA

于 2013-09-10T00:52:16.587 に答える
2

IDisposable オブジェクトを返す場合、それを破棄するのは呼び出し元の責任です。

public IDisposable MakeDisposableObject()
{
    return new SqlConnection(""); // or whatever
}

発信者:

using (var obj = MakeDisposableObject())
{
}

メソッドがオブジェクトを破棄してから返すことは、あまり意味がありません。破棄されたオブジェクトは、呼び出し元にとって何の価値もありません。一般に、破棄された破棄可能なオブジェクトを参照すると、ObjectDisposedException.

于 2013-09-10T01:05:24.073 に答える
1

いくつかの観察。

メソッドがないため、そのコードはコンパイルされobjectません.Dispose()

なぜあなたは使わないのですIDisposableか?

返されるオブジェクトを破棄するのはなぜですか。返すと、他のコードがそれを使用する目的でオブジェクトが返されるからです。何かを「処分する」という概念は、それ自体とその使用済みの管理されていないリソースをクリーンアップする機会を与えることです。他の場所で使用されるはずのオブジェクトを返しているが、オブジェクトが他の場所で使用される前にクリーンアップしたい管理されていないリソースがある場合、実際には 2 つの別個のオブジェクトが必要です。1 つは破棄可能なデータをロードするためのもので、もう 1 つは使用可能なロード済みコンテンツを含む別のオブジェクトです。この例は、.NET フレームワークのストリーム リーダーのようなものです。通常new、ストリームリーダーを使用して、byte[]または他のデータオブジェクトに読み込みます。.Dispose()ストリーム リーダー、return次にbyte[]. 適時に処分するリソースを持つ「ローダー」は、処分する必要なく使用できる「ロード済み」データを含むオブジェクトとは別のものです。

于 2013-09-10T01:01:13.043 に答える