В ... момент! Это кажется ошибкой в moment-timezone
(см. # 738 , # 258 ). Текущий обходной путь, который я нашел, состоит в том, чтобы сначала использовать moment.utc()
(который очищает часовой пояс, а также устанавливает момент в режиме «utc»), а затем moment.local()
. То есть moment.utc().local()
.
Технический термин для этого - то, что дженерики являются инвариантными в C# 3.0 и ранее. От C#4.0 вперед, работ броска.
Чем инвариантное средство состоит в том, что нет никаких отношений между двумя универсальными типами просто, потому что их универсальные параметры типа связаны (т.е. под - или супертипы друг друга).
В Вашем примере нет никаких отношений ввода между IEnumerable<object>
и IEnumerable<string>
, просто, потому что строка является подтипом объекта. Их просто считают двумя абсолютно несвязанными типами, как строка и интервал (они все еще, оба - подтипы объекта, но все),
Существует несколько обходных решений и исключений для этой проблемы, с которой Вы столкнулись.
Во-первых, можно бросить каждую строку индивидуально для возражения при использовании.NET 3.0, можно сделать то использование Cast<T>()
дополнительный метод. Иначе можно использовать foreach и поместить результат в новую переменную статического типа, который Вы хотите.
Во-вторых, массивы являются исключением для ссылочного типа, т.е. передающий в строке [] тип к методу, принимающему объект [], типы должны работать.
Как другие указали, типы дженериков являются инвариантными. IEnumerable<T>
могло быть ковариантным, но C# в настоящее время не поддерживает варианты определения. C# 4.0, как ожидают, будет поддерживать варианты, таким образом, это могло бы поддерживаться в будущем.
Для работы вокруг этого теперь, Вы можете с помощью дополнительный метод LINQ Cast<object>()
. Принятию Вас назвали метод Foo
это берет IEnumerable<object>>
. Можно назвать его как это,
Foo(stringEnumerable.Cast<object>());
Самый легкий способ передать IEnumerable<string>
функционировать, требуя IEnumerable<object>
посредством преобразования функции как это:
public IEnumerable<object> convert<T>(IEnumerable<T> enumerable)
{
foreach (T o in enumerable)
yield return o;
}
Когда C# 4 выйдет, это не будет необходимо, потому что он будет поддерживать ковариантность и контравариантность.
Необходимо использовать
IEnumerable<T>
если Вы хотите передать в различных типах, то можно запросить T для обнаружения то, что вводит его.
Хороший способ думать об этом состоит в том, чтобы спросить себя, "Что произошло бы, если Вы могли бы сделать это?". Возьмите следующий пример:
IEnumerable<String> strings=...;
IEnumerable<Object> objects = strings; // assume this were legal
objects.Add(new Integer(5)); // what the...
Мы просто добавили целое число к списку строк. Компилятор делает это для сохранения безопасности типов.