Метод добавления LinkedList (T) - PullRequest
1 голос
/ 06 февраля 2009

Метод Add из интерфейса ICollection (T) был явно реализован классом LinkedList (T) - . В этой коллекции вместо этого есть методы AddFirst и AddLast (среди прочих). Явно реализованный метод отображается на AddLast-метод. Это имеет ряд недостатков и ИМХО вообще никакой пользы. Два главных недостатка:

  1. Вы не можете использовать инициализацию коллекции в LinkedList (T), поскольку для этого требуется метод Add.
  2. Если вы использовали, скажем, List (T) в методе и хотите изменить его на использование LinkedList (T), вместо этого вам придется обновить все вызовы на Add для вызова AddLast вместо этого.

Я думаю об этом так: никогда не следует явно реализовывать элементы интерфейса, если они вообще не имеют смысла, когда вы знаете конкретный тип. Например, метод Add должен быть явно реализован (и эффективно скрыт), если вы реализуете ICollection (T) только для чтения.

Существуют ли другие примеры методов, которые были явно реализованы, которых не должно было быть в платформе?

В качестве примечания: Чтобы решить проблему с номером 2, вы можете создать метод расширения «Добавить» для класса LinkedList (T).

1 Ответ

4 голосов
/ 06 февраля 2009

Метод Add был бы неоднозначным, поэтому я доволен явной реализацией ...

Queue[<T>] и Stack[<T>] имеют похожее поведение.

Для других (не входящих) любопытных явных членов - как насчет DbParameter.Precision и DbParameter.Scale.

В связи с проблемой переноса между ними - вы всегда можете написать ToLinkedList<T> метод расширения для IEnumerable<T>.

В качестве альтернативы - метод расширения AddRange<T> имеет большое значение ...

static void Main()
{
    var list = new LinkedList<int>();
    list.AddRange(1, 2, 3, 4, 5);
}
static void AddRange<T>(this ICollection<T> list, params T[] values)
{
    foreach (T value in values)
    {
        list.Add(value);
    }
}

( EDIT ) Вы также можете использовать «свободный» API, если вы хотите использовать его как одно выражение:

static void Main()
{
    var list = new LinkedList<int>().AddRange(1, 2, 3, 4, 5);
    // `list` is correctly a LinkedList<int> here
}
static TCollection AddRange<TCollection, TValue>(
    this TCollection collection, params TValue[] values)
    where TCollection : ICollection<TValue>
{
    foreach (TValue value in values)
    {
        collection.Add(value);
    }
    return collection;
}
...