Это не сработает, поскольку не существует неявного преобразования между List<doohickey>
и IEnumerable<NotifyPropertyChanging>
. Вам нужно позвонить:
Update(doohickeys.Cast<INotifyPropertyChanging>());
Причиной этого является безопасность типов. В C # 4 к языку была добавлена ко-/ контравариантность, что обычно помогает сделать этот тип преобразований действительным. Однако существуют некоторые ограничения, поскольку соответствующий тип должен быть объявлен со-/ контравариантным и применяется только к интерфейсам и делегатам.
Причина, по которой вы не можете неявно преобразовать List<T>
в List<TBase>
, состоит в том, что он сделает этот код действительным:
List<T> values = new List<T>();
// add some values...
List<TBase> bases = values;
bases.Add(new TBase()); // Woops. We broke type safety by adding a TBase to a list of T's
Теперь, если вы попытаетесь сделать это, когда values
имеет тип IEnumerable<T>
, это будет допустимо в C # 4. Это потому, что вы можете только получить значения из IEnumerable<T>
, поэтому нам не нужно беспокоиться о добавлении меньших типов. Поэтому IEnumerable<T>
является ковариантным и объявляется как:
IEnumerable<out T>
Где out
означает «ковариантный». (На самом деле ключевые слова - это лучший способ запомнить, каким образом значения могут идти в типе варианта.
Сопротивление / контравариантность - довольно обширный предмет, , но эта статья хорошо объясняет самые важные части . И если вы хотите узнать больше, у Эрика Липперта есть серия из 11 статей в блоге об этой функции. Эрик - один из языковых дизайнеров.