9

値型であるジェネリック型パラメーターがあり、値がデフォルトと等しいかどうかを知りたい場合は、次のようにテストします。

static bool IsDefault<T>(T value){
    where T: struct
    return value.Equals(default(T));
}

ジェネリック型パラメーターがない場合は、リフレクションを使用する必要があるようです。メソッドがすべての値型で機能する必要がある場合、ここで行っていることよりもこのテストを実行するためのより良い方法はありますか?:

static bool IsDefault(object value){
   if(!(value is ValueType)){
      throw new ArgumentException("Precondition failed: Must be a ValueType", "value");
   }
   var @default = Activator.CreateInstance(value.GetType());
   return value.Equals(@default);  
}

ちなみに、Nullable構造体の評価に関して、ここで考慮していないことはありますか?

4

4 に答える 4

8

次の拡張方法が便利で、すべてのタイプで機能することがわかりました。

public static object GetDefault(this Type t)
{
    return t.IsValueType ? Activator.CreateInstance(t) : null;
}

public static T GetDefault<T>()
{
    var t = typeof(T);
    return (T) GetDefault(t);
}

public static bool IsDefault<T>(T other)
{
    T defaultValue = GetDefault<T>();
    if (other == null) return defaultValue == null;
    return other.Equals(defaultValue);
}
于 2011-08-15T17:56:33.740 に答える
4

古い質問ですが、受け入れられた答えは私にはうまくいきませんので、私はこれを提出します(おそらくもっと良くすることができます):

public static object GetDefault(this Type type)
{   
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        var valueProperty = type.GetProperty("Value");
        type = valueProperty.PropertyType;
    }

    return type.IsValueType ? Activator.CreateInstance(type) : null;
}

次の結果が得られます。

typeof(int).GetDefault();       // returns 0
typeof(int?).GetDefault();      // returns 0
typeof(DateTime).GetDefault();  // returns 01/01/0001 00:00:00
typeof(DateTime?).GetDefault(); // returns 01/01/0001 00:00:00
typeof(string).GetDefault();    // returns null
typeof(Exception).GetDefault(); // returns null
于 2013-07-16T14:04:58.387 に答える
2

ValueType単純化するためのパラメータとして必要です:

static bool IsDefault(ValueType value){
   var @default = Activator.CreateInstance(value.GetType());
   return value.Equals(@default);  
}
于 2011-08-15T17:11:36.237 に答える
0

ちなみに、Nullable構造体の評価に関して、ここで考慮していないことはありますか?

はい、何かが足りません。のパラメータとしてを使用することにより、objectボックスタイプへのコードの呼び出しが必要になりますNullable<T>(これにより、それらはnullまたはT値に変換されます)。したがって、nullableを渡すと、値型になることはないis/throwため、がスローされます。null

編集: @cdhowieが言ったように、nullをチェックする必要があります。これはNullable型でも機能します。

于 2011-08-15T17:27:53.700 に答える