Я понимаю, что на вопрос уже дан ответ, но я упустил простое объяснение проблемы, стоящей за вашим вопросом, поэтому вот так:
Причина, по которой вы не можете присвоить свой класс SampleDataSource
полю IEnumerable<object>
, заключается в том, что SampleDataSource
не реализует IEnumerable<object>
. Хотя он реализует IEnumerable
, этого недостаточно, потому что IEnumerable<object>
является подтипом из IEnumerable
.
Из-за ковариации интерфейса вы сможете присвоить класс полю IEnumerable<object>
, если оно реализует IEnumerable<MyObject>
, при условии, что MyObject на самом деле является ссылочным типом (то есть классом) , Однако это применимо только к C # 4.0 и более поздним версиям.
В ответе Рида Копси не упоминается, что вы могли бы объявить класс SampleDataSource таким образом, потому что IEnumerable<T>
наследуется от IEnumerable
:
public class SampleDataSource : IEnumerable<MyObject>
Далее, поскольку вы просто оборачиваете вложенную коллекцию, вы обычно реализуете ее следующим образом:
public class SampleDataSource : IEnumerable<MyObject>
{
public List<MyObject> Subjects { get; private set; }
public IEnumerator<MyObject> GetEnumerator()
{
return Subjects.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Это сомнительно с точки зрения объектной ориентации, поскольку вы предоставляете общественности доступ для чтения и записи к списку. (Тот факт, что установщик является частным, означает, что общедоступный не может переназначить ссылку на список, но это не мешает им вызывать Add
или Remove
или Clear
в списке.)
Еще один вопрос об ориентации объекта будет заключаться в следующем: если SampleDataSource содержит последовательность MyObjects, почему он также будет последовательностью MyObjects? Вместо этого:
classICannotAlter.Items = (IEnumerable<object>)someSampleDataSourceInstance;
Может быть, вы должны делать это:
classICannotAlter.Items = (IEnumerable<object>)someSampleDataSourceInstance.Subjects;