Кастинг от IEnumerable <объект> к IEnumerable <строка>

В ... момент! Это кажется ошибкой в ​​moment-timezone (см. # 738 , # 258 ). Текущий обходной путь, который я нашел, состоит в том, чтобы сначала использовать moment.utc() (который очищает часовой пояс, а также устанавливает момент в режиме «utc»), а затем moment.local(). То есть moment.utc().local().

6
задан Wasif Hossain 18 February 2014 в 06:25
поделиться

5 ответов

Технический термин для этого - то, что дженерики являются инвариантными в C# 3.0 и ранее. От C#4.0 вперед, работ броска.

Чем инвариантное средство состоит в том, что нет никаких отношений между двумя универсальными типами просто, потому что их универсальные параметры типа связаны (т.е. под - или супертипы друг друга).

В Вашем примере нет никаких отношений ввода между IEnumerable<object> и IEnumerable<string>, просто, потому что строка является подтипом объекта. Их просто считают двумя абсолютно несвязанными типами, как строка и интервал (они все еще, оба - подтипы объекта, но все),

Существует несколько обходных решений и исключений для этой проблемы, с которой Вы столкнулись.

Во-первых, можно бросить каждую строку индивидуально для возражения при использовании.NET 3.0, можно сделать то использование Cast<T>() дополнительный метод. Иначе можно использовать foreach и поместить результат в новую переменную статического типа, который Вы хотите.

Во-вторых, массивы являются исключением для ссылочного типа, т.е. передающий в строке [] тип к методу, принимающему объект [], типы должны работать.

11
ответ дан 8 December 2019 в 05:58
поделиться

Как другие указали, типы дженериков являются инвариантными. IEnumerable<T> могло быть ковариантным, но C# в настоящее время не поддерживает варианты определения. C# 4.0, как ожидают, будет поддерживать варианты, таким образом, это могло бы поддерживаться в будущем.

Для работы вокруг этого теперь, Вы можете с помощью дополнительный метод LINQ Cast<object>(). Принятию Вас назвали метод Foo это берет IEnumerable<object>>. Можно назвать его как это,

Foo(stringEnumerable.Cast<object>());
8
ответ дан 8 December 2019 в 05:58
поделиться

Самый легкий способ передать IEnumerable<string> функционировать, требуя IEnumerable<object> посредством преобразования функции как это:

public IEnumerable<object> convert<T>(IEnumerable<T> enumerable)
    {
    foreach (T o in enumerable)
        yield return o;
    }

Когда C# 4 выйдет, это не будет необходимо, потому что он будет поддерживать ковариантность и контравариантность.

3
ответ дан 8 December 2019 в 05:58
поделиться

Необходимо использовать

IEnumerable<T> 

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

0
ответ дан 8 December 2019 в 05:58
поделиться

Хороший способ думать об этом состоит в том, чтобы спросить себя, "Что произошло бы, если Вы могли бы сделать это?". Возьмите следующий пример:

IEnumerable<String> strings=...;
IEnumerable<Object> objects = strings; // assume this were legal

objects.Add(new Integer(5)); // what the...

Мы просто добавили целое число к списку строк. Компилятор делает это для сохранения безопасности типов.

0
ответ дан 8 December 2019 в 05:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: