Как получить значение по умолчанию для Типа ValueType с отражением - PullRequest
9 голосов
/ 15 августа 2011

Если у меня есть параметр универсального типа, который является типом значения, и я хочу знать, равно ли значение значению по умолчанию, я проверяю его следующим образом:

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 ]

8 голосов
/ 15 августа 2011

Я нашел следующие методы расширения полезными и буду работать для всех типов:

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);
}
3 голосов
/ 16 июля 2013

Старый вопрос, но принятый ответ не работает для меня, поэтому я отправляю это (вероятно, можно сделать лучше):

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
2 голосов
/ 15 августа 2011

Я бы потребовал ValueType в качестве параметра для упрощения:

static bool IsDefault(ValueType value){
   var @default = Activator.CreateInstance(value.GetType());
   return value.Equals(@default);  
}
0 голосов
/ 15 августа 2011

Кстати, есть что-то, с чем я не рассматриваю здесь уважение к оценке Nullable структур?

Да, вы что-то упустили. Принимая object в качестве параметра, вы требуете вызова кода для ввода Nullable<T> типов (что преобразует их в ноль или в их T значение). Поэтому, если вы передадите nullable, ваш is/throw скинет, потому что null никогда не будет типом значения.

Редактировать: Как сказал @cdhowie, вам нужно проверить на нулевое значение. Это будет работать и для типов Nullable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...