0

うーん!エラーが表示された理由がわからなかったので、これを質問として投稿するつもりでした...しかし、もちろん、それを見ると明らかです今頭を叩いてます。楽しみのためにここに残しておきます。あなたがそれをキャッチできるかどうかを確認してください。

今夜、WeakDictionary クラスに TryGetValue を実装しているときに、奇妙なことに遭遇しました。エラーが発生し、理由がわかりません。

コードは次のとおりです。

public bool TryGetValue(TKey key, out TItem value)
{
    WeakReference<TItem> weakReference;

    if(_itemStorage.TryGetValue(key, out weakReference))
        if(weakReference.TryGetTarget(out value))
            return true;
    else
        value = default(TItem);

    return false;
}

これが私が得ているエラーです:

制御が現在のメソッドを離れる前に、out パラメータ 'value' を割り当てる必要があります。

私には、すべてのコードパス戻る前に「値」を設定しているように見えます。

最初の 'if' が失敗した場合、'else' 句は 'value' を設定します。

ただし、最初の「if」が合格した場合、次の行「weakReference.TryGetTarget」は、警告されているのとまったく同じ理由で「値」を設定しません(つまり、「TryGetTarget」には「out」パラメーター自体があるため、戻る前に out パラメータを内部的に設定する必要があります)?

私が言ったように、私は明らかな何かを見逃していました。(睡眠が必要だ!)

4

3 に答える 3

7

問題は、最初の if ステートメントが失敗した場合、初期化されていない値が残るという事実にあります。

if基本的に、ステートメントに中括弧がありません。これにより、elseステートメントが適切に適切にアタッチされますif

if (_itemStorage.TryGetValue(key, out weakReference))
{
    if (weakReference.TryGetTarget(out value))
        return true;
}

ドキュメントはこれを明確にします:

then-statement および else-statement 内の 1 つまたは複数のステートメントは、元の if ステートメント内にネストされた別の if ステートメントを含め、任意の種類にすることができます。ネストされた if ステートメントでは、各 else 句は最後の if に属し、対応する else はありません。

これは、else句が外側ではなく内側のifステートメントに関連付けられていることを意味します。

これを次のように書き直すこともできます。

public bool TryGetValue(TKey key, out TItem value)
{
    WeakReference<TItem> weakReference;

    if (_itemStorage.TryGetValue(key, out weakReference))
        return weakReference.TryGetTarget(out value);

    value = default(TItem);
    return false;
}
于 2015-09-20T06:08:31.813 に答える
4

elseステートメントを削除します。

@Yuvalの回答と事実上同じですが、コードを削除するのが好きです。

public bool TryGetValue(TKey key, out TItem value)
{
  WeakReference<TItem> weakReference;

  if(_itemStorage.TryGetValue(key, out weakReference))
    if(weakReference.TryGetTarget(out value))
        return true;

  value = default(TItem);

  return false;
}

また、 ;if(c1) if(c2)と同等であることに注意してください。if (c1 && c2)どちらの方が読みやすく、問題はありません。

于 2015-09-20T06:11:46.067 に答える
2

あなたのコードは次のようにコンパイルされています:

public bool TryGetValue(TKey key, out TItem value)
{
    WeakReference<TItem> weakReference;

    if (_itemStorage.TryGetValue(key, out weakReference))
    {
        if (weakReference.TryGetTarget(out value))
        {
            return true;
        }
        else
        {
            value = default(TItem);
        }
    }

    return false;
}

このコードではvalue、最初の変数ifが false の場合、変数は設定されていません。

あなたが本当に欲しかったもの、そしてあなたが手に入れたと思ったものはこれでした:

public bool TryGetValue(TKey key, out TItem value)
{
    WeakReference<TItem> weakReference;

    if (_itemStorage.TryGetValue(key, out weakReference))
    {
        if (weakReference.TryGetTarget(out value))
        {
            return true;
        }
    }
    else
    {
        value = default(TItem);
    }

    return false;
}

これは、中括弧を指定せず、の列位置elseが正しいと想定する危険性があります。

于 2015-09-20T06:33:03.203 に答える