次のように定義された汎用メソッドがあります。
public void MyMethod<T>(T myArgument)
最初に行うことは、myArgument の値がその型のデフォルト値であるかどうかを確認することです。次のようになります。
if (myArgument == default(T))
しかし、T が == 演算子を実装することを保証していないため、これはコンパイルされません。そこで、コードを次のように変更しました。
if (myArgument.Equals(default(T)))
これでコンパイルは成功しますが、myArgument が null の場合は失敗します。これは私がテストしている内容の一部です。次のように明示的な null チェックを追加できます。
if (myArgument == null || myArgument.Equals(default(T)))
これは冗長に感じます。ReSharper は、myArgument == null 部分を、開始点である myArgument == default(T) に変更することを提案しています。この問題を解決するより良い方法はあるでしょうか?
参照型と値型の両方をサポートする必要があります。
ベストアンサー1
ボックス化を回避するには、ジェネリックの等価性を比較する最良の方法は を使用することですEqualityComparer<T>.Default
。これはIEquatable<T>
(ボックス化なしで) と を尊重しobject.Equals
、すべてのNullable<T>
「持ち上げられた」ニュアンスを処理します。したがって、次のようになります。
if(EqualityComparer<T>.Default.Equals(obj, default(T))) {
return obj;
}
これは次のものと一致します:
- クラスの場合はnull
- null(空)の場合
Nullable<T>
- 他の構造体の場合はゼロ/偽など