4

一部の C# コードでは、linq GroupBy<TSource, TKey>()メソッドをカスタムで使用していますIEqualityComparer<T>

GroupBy(x => x.SomeField, new FooComparer());

グループ化キーとして使用するフィールドは、null. 結果として、メソッドにいくつかのnullチェックを追加する必要がありましたEquals():

public bool Equals(Foo x, Foo y)
{
    if (x == null && y == null)
       return true;
    else if (x == null && y != null)
       return false;
    else if (x != null && y == null)
       return false;
    else 
       return x.Id == y.Id;
}

GetHashCode()問題は、関数で同じことを行う必要があるかどうかです。

public int GetHashCode(Foo obj)
{
    if (obj == null)          //is this really needed ?
       return default(int);   //
    else
       return obj.Id;
}

私が理解していない何か:GroupBy()メソッドで提供されたnullキーを使用しても、objパラメーターGetHashCode()のオブジェクトで呼び出されることはありません。null誰かが私に理由を説明できますか? GroupBy()(方法が実装されており、要素の順序がそれに与えられているため、それは単なる「純粋なチャンス」ですか?)


編集 :

caerolusが指摘したように、実装にはいくつかの特別なチェックが行われますGroupBy()

私はチェックインしILSpyGroupBy()実装されていますLookup<TKey, TElement>

これがrevelant関数です:

internal int InternalGetHashCode(TKey key)
{
    if (key != null)
    {
        return this.comparer.GetHashCode(key) & 2147483647;
    }
    return 0;
}
4

1 に答える 1

5

のドキュメントにIEqualityComparer<T>.GetHashCodeよると:

ArgumentNullException
の型はobj 参照型で、nullです。obj

したがって、これはそのインターフェイスの契約の一部であり、そのため注意する必要があります。ArgumentNullExceptionif objisをスローして実装しnullます。

コードが気にしない部分に決して触れないことが疑われる場合、または証明できる場合でも、常にインターフェイスに準拠する必要があります。後で変更すると、その動作に依存するコードが導入される可能性があります。

于 2013-04-11T12:24:01.563 に答える