Вопрос о двух разных шаблонах расширения классов - PullRequest
3 голосов
/ 22 июля 2011

В чем семантическая разница между следующими двумя методами:

public static bool IsNullOrEmpty(this Array value)
{
    return (value == null || value.Length == 0);
}

и

public static bool IsNullOrEmpty<T>(this T[] value)
{
    return (value == null || value.Length == 0);
}

Есть ли преимущество одного над другим?

Ответы [ 3 ]

4 голосов
/ 22 июля 2011

Первый будет работать для любого массива , включая прямоугольные массивы и массивы с ненулевой нижней границей.Он также будет работать, когда тип времени компиляции массива просто Array, что может случаться очень редко с довольно слабым типом API.

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

(я предполагаю, что вы не хотите от этого каких-либо «дополнительных» функций, таких как дополнительные ограничения для T во второй форме ...вам просто нужно что-то, что будет определять, является ли ссылка на массив нулевой или ссылается на пустой массив.)

РЕДАКТИРОВАТЬ: Для IEnumerable вы должны использовать:

public static bool IsNullOrEmpty(this IEnumerable value)
{
    if (value == null)
    {
        return true;
    }
    var iterator = value.GetEnumerator();
    try
    {
        return !iterator.MoveNext();
    }
    finally
    {
        // Non-generic IEnumerator doesn't extend IDisposable
        IDisposable disposable = iterator as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }
}

недостатком этого, конечно, является то, что он может очень легко иметь побочные эффекты - например, вы можете передать запрос LINQ, который в конечном итоге будет говорить с базой данных.

2 голосов
/ 22 июля 2011

С появлением универсального выражения вы можете добавить условие, которое еще больше ограничивает значение T ...

Таким образом, вы можете ограничить его словами "где T: класс" или "где T: ISomeInterface" (особенно выможет сделать «где T: IDisposable» и убедиться, что ваше расширение не может использовать ничего, что не может распоряжаться

1 голос
/ 22 июля 2011

Второй использует дженерики, поэтому является типобезопасным.

...