Как «обобщить» этот метод расширения? - PullRequest
0 голосов
/ 31 марта 2011

У меня есть следующий метод, который в настоящее время работает на int? переменные. Я хотел бы расширить его на любые числовые переменные, допускающие значение NULL (например, десятичные ?, двойные? И т. Д.)

public static bool IsNullOrInvalid(this System.Nullable<int> source)
{
    return (source == null || source == -1);
}

Как я могу это осуществить?

Ответы [ 3 ]

8 голосов
/ 31 марта 2011

Хитрый бит выясняет, что означает «недействительный» в каждом случае.Если «любое значение, которое считается меньшим, чем значение по умолчанию для типа данных», можно попробовать:

public static bool IsNullOrNegative<T>(this T? source)
    where T : struct, IComparable<T>
{
    return source == null || source.Value.CompareTo(default(T)) < 0;
}

РЕДАКТИРОВАТЬ: как отмечено в комментариях, нет «числового» ограничения - оно будет действительнымвызывать этот метод для каждого типа значения, сравнимого с самим собой, например DateTime.Этого нельзя избежать - добавление большего количества ограничений, вероятно, немного уменьшит набор, но не полностью.

Что касается сравнения с ровно -1, вам необходимо иметь возможность определить значение "-1«для каждого типа.Там нет общего способа сделать это.Вы могли бы вручную построить Dictionary<Type, object> из "-1 для каждого интересующего меня типа", но это было бы довольно уродливо.

Если -1 неверно, это действительно -2действует?Это странно для меня.

0 голосов
/ 31 марта 2011

Вы не можете, чтобы сделать это возможным, вам понадобится

public static bool IsNullOrInvalid<T>(this System.Nullable<T> source) where T : Numeric

но нет базового класса Numeric для чисел в c #.
Проблема в source == -1, нет общего класса или интерфейса, который работает с -1.

Вы могли бы вспыхнуть -1

public static bool IsNullOrInvalid<T>(this System.Nullable<T> source, T invalid)
    where T: struct, IEquatable<T>
{
    return (source == null || source.Value.Equals(invalid));
}

Но тогда вам нужно позвонить вот так

int? foo = -1;
var isInvalid = foo.IsNullOrInvalid(-1);
0 голосов
/ 31 марта 2011

Я не думаю, что это возможно, потому что, чтобы сделать это универсальным, он должен быть универсальным для всех типов, а недействительный характерен для целого числа.Если вы просто перегрузите этот метод (double, float и т. Д.), Компилятор должен выяснить, какой из них вам нужен, когда вы наберете

(0.0).IsNullOrValid()
...