2012-07-10 7 views
7

私の(単位)テストカバレッジがまだかなり低いので、残念ながら、私は多くのエラーを難しい方法で見つけなければなりません。したがって、リファクタリング時には、C#コンパイラの型チェックに大きく依存しています。タイプセーフなEquals()

今日、リファクタリング時に導入されたバグをx.Equals(aThingWrappingOriginalThing)という行で紛失した問題を修正しました。 bool Equals(object T)のように、コンパイラは不平を言っていませんでした。しかし、私がEquals()を(BCLの代わりに)直接使用する時間の90%は、同じタイプのオブジェクトを論理的に比較するつもりです。

今私はこのような状況のためにEquals()の型セーフバージョンを宣伝している人は見たことがないのですが(C#)。これにはベストプラクティスがありますか?

そうように私は、これらのcomparisionsのための拡張メソッドを使用するように誘惑しています:

public static bool SafeEquals<T>(this T a, T b) 
{ 
    if (a == null) return b == null; 
    return a.Equals(b); 
} 
public static bool SafeEquals<X>(this IEquatable<X> a, IEquatable<X> b) 
{ 
    if (a == null) return b == null; 
    return a.Equals(b); 
} 

は、これらが最適化されていませんか? http://rickyclarkson.blogspot.com/2006/12/making-equalsobject-type-safe.html

+0

トピックの背景は次のとおりです。http://blogs.msdn.com/b/ericlippert/archive/2009/04/09/double-your-dispatch-double-your-fun.aspx – Vlad

答えて

5

(実装されている場合)、これは潜在的にボクシングEquals(object)を使用して、他の、IEquatable<T>をサポートしています。 Nullable<T>のサポート(ボクシングなし)を含む、クラスと構造体をサポートしています。

+0

ありがとう、素晴らしい音。拡張メソッドにラップするとパフォーマンスが低下しますか?インライン化されますか? – Equalizer

+0

@Equalizerの拡張メソッドはstatic-callなので、そうではありません。 .Defaultは、使用される戦略に応じて、いくつかの具体的な実装のインスタンスであるため、傾いている可能性は低いです。決定/リフレクションはTごとに1回だけ行われるため、キャッシュされますが、インライン化はされません。 –

2

私は何を見ることは私にはよさそうだ:

は、ここで私は、Javaのため、見つかったトピックについてのみブログ記事です。

私の2セント:意図した動作から外れることになるで非常に少数の例があります

public static bool SafeEquals<T>(this T a, T b) 
{ 
    return object.Equals(a, b); 
} 

:私はnullチェックをスキップするために簡単であり、これを使用すると思います。そのうちの1つは、Equalsが両方のオブジェクトが同じオブジェクトである場合にfalseを返す場合です(これは決して発生しません)。

参考のために、ここでは逆コンパイルされたobject.Equalsがありますので、何が起こるかを自分で確認できます。あなたは

EqualityComparer<T>.Default.Equals(x,y); 

を探している

public static bool Equals(object objA, object objB) 
{ 
    return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB))); 
} 
+0

'オブジェクト。等しいかどうかチェックします。両者がヒープ上の同じデータを指しているかどうかを調べます。 –

+0

@Kendallここで最初に実装されたのは、オブジェクトのラッパーです.Equalsでは、コンシューマーにオブジェクトを呼び出させるだけではなく、なぜなら – Jason

+0

@ColeJohnsonの価値があるすべてのものをデフォルトにします。しかし、「Equals」と「ReferenceEquals」の違いがあります –

関連する問題