#.net #list #types #ienumerable
#.net #Список #типы #ienumerable
Вопрос:
Учитывая IEnumerable, как я могу проверить, является ли его тип List?
Учитывая IEnumerable, я хочу использовать методы списка, но если это уже список, я просто приведу его, а не использую .ToList()
Ответ №1:
Используйте is
оператор для проверки типа переменной.
if(myIEnumerable is IList)
{
// it is a List (may still need casting in order to use List specific methods)
}
Комментарии:
1. Разве IList не был бы немного более общим?
Ответ №2:
List list = (yourEnumerable as List) ?? yourEnumerable.ToList();
Комментарии:
1. Здесь также следует использовать
IList
вместоList
2. Может иметь смысл, но OP запросил список.
Ответ №3:
var myList = myIEnumerable as List ?? myIEnumerable.ToList();
или
var myList = (myIEnumerable as List<Type>) ?? myIEnumerable.ToList();
Ответ №4:
Вы можете использовать операторы is
или as
.
Ответ №5:
Пара способов:
List<int> list = myColl as List<int>;
if (list != null) // ...
или
if (myColl is List<int>) // ...
или
if (myColl.GetType() == typeof(List<int>) // ...
Ответ №6:
Я часто хотел иметь больший выбор интерфейсов, связанных с коллекцией, особенно ICountableEnumerable и IReadableByIndex. Первое могло быть добавлено при разработке .Net без добавления дополнительного кода разработчиками; первое, вероятно, потребовало бы добавления метода GetByIndex, чтобы избежать конфликтов с индексатором чтения / записи, присутствующим в полном IList, но, ИМХО, все равно было бы полезным дополнением, поскольку оно может быть контравариантным.
Как бы то ни было, возможно, что объект может быть универсальным IList, но не очень удобным для ваших целей, потому что это может быть IList типа, который является производным от ожидаемого вами типа. Например, если ваша процедура ожидала IEnumerable (от Car), но была передана IList (от HondaCivic), было бы неплохо, если бы вы могли использовать ее функцию чтения по индексу. Если IList (из T) унаследован от IReadableByIndex (из T), как описано выше, IList (из HondaCivic) может быть преобразован в IReadableByIndex (из Car). К сожалению, такое приведение невозможно с интерфейсом чтения-записи.
Тем не менее, использование общей процедуры для обработки списка может позволить избежать ненужного преобразования даже в таком случае. Следующий короткий класс VB иллюстрирует:
Класс GenericTest Класс MyThing Общедоступное значение в виде строки Дополнительный новый (ввод X в виде строки) Значение = X End Sub Конечный класс Класс myDerived Наследует MyThing Дополнительный новый (ввод x в виде строки) MyBase.New(x) End Sub Конечный класс Общий вспомогательный обратный отпечаток (из T как MyThing) (используя список как IEnumerable (из T)) Затемнить список как IList (из T) = TryCast(список, IList (из T)) Если castAsList ничего не значит, то castAsList = Список.ToList Отладка.Печать ("Преобразование в список") Ещё Отладка.Печать ("Список был хорошим") Завершить, если Для i как Integer = castAsList.Количество - от 1 до 0 Шаг -1 Отладка.Печать (castAsList(i).Значение.toString) Далее End Sub Общий вспомогательный тест () Затемнить myList как новый список (из myDerived) Для i как целого числа = от 1 до 5 myList.Add(Новый myDerived("Item" amp; i.toString)) Далее Обратный вывод (myList) Обратный отпечаток (MyThing) (myList) End Sub Конечный класс
Функция ReversePrint приводит или преобразует IEnumerable в IList и выводит его в обратном порядке. Обратите внимание, что подпрограмма действительно «ожидает» IEnumerable (от MyThing), но принимает его параметр как IEnumerable (от T). Таким образом, если компилятор знает, что он реализует IEnumerable (из myDerived), он может предложить MyDerived в качестве параметра типа. При этом объект может быть приведен к IList (из MyDerived). Если кто-то запрещает общему параметру соответствовать исходному объекту, объект будет передан подпрограмме просто отлично, но примерное приведение к типу не сработает, и, таким образом, будет необходимо преобразовать элемент в IList, соответствующий переданному параметру type.
PS— Одним из пунктов моего списка пожеланий для .Net 5.0 была бы возможность для интерфейса указывать реализацию метода по умолчанию для использования в случае, если класс, который должен реализовать метод, его не предоставляет. Это могло бы позволить Microsoft наследовать IList от контравариантного интерфейса IReadableByIndex (и, возможно, ковариантных интерфейсов IWritableByIndex и IAppendable) без нарушения существующего кода.