Ответы на такие вопросы: List <T> или IList <T> всегда, похоже, согласны с тем, что возврат интерфейса лучше, чем возврат конкретной реализации коллекции. Но я борюсь с этим. Создание экземпляра интерфейса невозможно, поэтому, если ваш метод возвращает интерфейс, он фактически все еще возвращает определенную реализацию. Я немного экспериментировал с этим, написав два небольших метода:
public static IList<int> ExposeArrayIList()
{
return new[] { 1, 2, 3 };
}
public static IList<int> ExposeListIList()
{
return new List<int> { 1, 2, 3 };
}
И используйте их в моей тестовой программе:
static void Main(string[] args)
{
IList<int> arrayIList = ExposeArrayIList();
IList<int> listIList = ExposeListIList();
//Will give a runtime error
arrayIList.Add(10);
//Runs perfectly
listIList.Add(10);
}
В обоих случаях, когда я пытаюсь добавить новое значение, мой компилятор не дает мне никаких ошибок, но, очевидно, метод, который предоставляет мой массив как IList<T>
, дает ошибку времени выполнения, когда я пытаюсь что-то добавить к нему.
Поэтому люди, которые не знают, что происходит в моем методе, и должны добавлять к нему значения, вынуждены сначала скопировать мой IList
в List
, чтобы иметь возможность добавлять значения без риска ошибок. Конечно, они могут сделать typecheck, чтобы узнать, имеют ли они дело с List
или Array
, но если они этого не делают, и они хотят добавить элементы в коллекцию , у них нет другого выбор для копирования IList
в List
, даже если он уже является List
. Если массив никогда не отображается как IList
?
Другая моя забота основана на принятом ответе связанного вопроса (акцент мой):
Если вы публикуете свой класс через библиотеку, которую будут использовать другие, , вы, как правило, хотите выставить ее через интерфейсы, а не конкретные реализации. Это поможет, если вы решите изменить реализацию своего класса позже использовать другой конкретный класс. В этом случае пользователям вашей библиотеки не потребуется обновлять свой код, так как интерфейс не изменяется.
Если вы просто используете его внутренне, вам может быть не так много, и использование List может быть в порядке.
Представьте, что кто-то действительно использовал мой IList<T>
, который они получили из моего метода ExposeListIlist()
, как раз для добавления/удаления значений. Все работает нормально. Но теперь, как и в ответе, потому что возврат интерфейса более гибкий, я возвращаю массив вместо списка (без проблем на моей стороне!), Тогда они готовы к лечению...
TL;DR:
1) Нарушение интерфейса вызывает ненужные приведения? Не имеет значения?
2) Иногда, если пользователи библиотеки не используют бросок, их код может сломаться при изменении вашего метода, хотя метод остается в полном порядке.
Я, наверное, слишком задумываюсь об этом, но я не понимаю общего мнения о том, что возврат интерфейса предпочтительнее, чем возвращение реализации.