Почему в .NET нет интерфейса IArray (T)?
Верьте или нет, я пошел вперед и включил этот интерфейс вбиблиотека с открытым исходным кодом I 'мы начали, Tao.NET, янаписал сообщение в блоге объясняя эту библиотекуIArray
интерфейс, который не только решает проблемы, которые я первоначально поднял в этом вопросе (год назад ?!), но также обеспечиваетковариантный индексированный интерфейс, что-то, что'Очень не хватает (на мой взгляд) в BCL.
Я спросил, почему .NET имеетIList
, который реализуетICollection
и, следовательно, предоставляет методы для изменения списка (,Add
Remove
и т. д.), но непредложить любой промежуточный интерфейс, такой какIArray
обеспечить произвольный доступ по индексу без какой-либо модификации списка.
В комментарии к Джону СкитуОригинальный ответ (в котором он спросил, как часто нужно иметь контракт, такой какIArray
Я упомянул, чтоKeys
а такжеValues
свойстваSortedList
классIList
а такжеIList
соответственно на что Джон ответил:
Но в этом случае этоs объявлен как IList, и вы знаете, просто использовать индексаторы. , , , Это'не очень элегантно, я согласен - но это не такНа самом деле это причиняет мне боль.
Это разумно, но я бы ответил, чтоэто нене причинит тебе никакой боли, потому что ты простознать вы можете'не делай этого, Нопричина ты знаешьне это'ясно из кода; Это'с тем, что у вас есть опыт работы сSortedList
учебный класс.
Visual Studio нене буду предупреждать меня, если я сделаю это:
SortedList mySortedList = new SortedList();
// ...
IList keys = mySortedList.Keys;
keys.Add("newkey");
Это'законно, согласноIList
, Но мы все знаем, этособирается вызвать исключение.
Гийом также сделал правильное замечание:
Ну, интерфейсы неЭто прекрасно, но разработчик может проверить свойство IsReadOnly перед вызовом Add / Remove / Set ...
Опять же, это разумно,НО: это не кажется вам немного окольным?
Предположим, я определил интерфейс следующим образом:
public interface ICanWalkAndRun {
bool IsCapableOfRunning { get; }
void Walk();
void Run();
}
Теперь предположим также, что я сделал это обычной практикой для реализации этого интерфейса, но только для егоWalk
Способ; во многих случаях я бы решил установитьIsCapableOfRunning
вfalse
и броситьNotSupportedException
наRun
...
Тогда у меня мог бы быть некоторый код, который был бы похож на это:
var walkerRunners = new Dictionary();
// ...
ICanWalkAndRun walkerRunner = walkerRunners["somekey"];
if (walkerRunner.IsCapableOfRunning) {
walkerRunner.Run();
} else {
walkerRunner.Walk();
}
Я сумасшедший или такой вид победы над целью интерфейса называется?ICanWalkAndRun
Я нахожу очень странным, что в .NET, когда я разрабатываю класс со свойством коллекции, которое обеспечивает произвольный доступ по индексу (или метод, который возвращает индексированную коллекцию и т. Д.),но не должен или не может быть изменен путем добавления / удаления элементови если захочусделать правильную вещь" В смысле ООП и предоставления интерфейса, чтобы я мог изменить внутреннюю реализацию, не нарушая API, я должен идти с этим.IList
Кажется, что стандартный подход заключается в реализацииIList
это явно определяет методы,Add
Insert
и т. д. - как правило, делая что-то вроде:
private List _items;
public IList Items {
get { return _items.AsReadOnly(); }
}
Но я вроде как ненавижу это. Если другой разработчик использует мой класс, и у моего класса есть свойство типаIList
, а такжевся идея интерфейса:Вот некоторые доступные свойства и методы "зачем мне бросатьNotSupportedException
(или в любом случае), когда он / она пытается сделать что-то, что, согласно интерфейсу, должно быть полностью законным?
Я чувствую, что реализация интерфейса и явное определение некоторых его членов - это как открытие ресторана и добавление некоторых пунктов в меню - возможно, в какой-то непонятной, простой пропущеннойчасть меню, нона меню тем не менее - это просто никогда не доступно.
Кажется, должно быть что-то вродеIArray
интерфейс, который обеспечивает очень простой произвольный доступ по индексу, но не добавляет / удаляет, как показано ниже:
public interface IArray {
int Length { get; }
T this[int index] { get; }
}
А потомIList
мог бы реализоватьICollection
а такжеIArray
и добавить его,IndexOf
Insert
а такжеRemoveAt
методы.
Конечно, я всегда мог написать этот интерфейс и использовать его сам, но это непомочь со всеми существующими классами .NET, которые нереализовать это. (И да, я знаю, что мог бы написать обертку, которая берет любойIList
и выплевываетIArray
, но серьезно?)
Кто-нибудь знает, почему интерфейсы вSystem.Collections.Generic
были разработаны таким образом? Я что-то пропустил? Есть ли веский аргумент что я'говорю о моих проблемах с подходом явного определения членов? I 'IList
я не пытаюсь казаться дерзким, как будто я знаю лучше, чем люди, которые разрабатывали классы и интерфейсы .NET; это просто нене имеет смысламне, Но я'Я готов признать тамСкорее всего, я не имеют принимается во внимание.