Следующий код:
public interface ISomeData
{
IEnumerable<string> Data { get; }
}
public class MyData : ISomeData
{
private List<string> m_MyData = new List<string>();
public List<string> Data { get { return m_MyData; } }
}
Выдает следующую ошибку:
ошибка CS0738: 'InheritanceTest.MyData' не реализует интерфейс 'InheritanceTest.ISomeData.Data. "InheritanceTest.MyData.Data" не может воплощать в жизнь 'InheritanceTest.ISomeData.Data' потому что у него нет соответствия возвращаемый тип 'System.Collections.Generic.IEnumerable'.
Поскольку список <T> реализует IEnumerable <T> , можно подумать, что мой класс будет реализовывать интерфейс. Может ли кто-нибудь объяснить, в чем причина этого не компиляции?
Как я вижу, есть два возможных решения:
- Измените интерфейс, чтобы быть более конкретным, и требуйте, чтобы IList был реализован.
- Измените мой класс (MyData), чтобы вернуть IEnumerable и реализовать оригинальный интерфейс.
Теперь предположим, что у меня также есть следующий код:
public class ConsumerA
{
static void IterateOverCollection(ISomeData data)
{
foreach (string prop in data.MyData)
{
/*do stuff*/
}
}
}
public class ConsumerB
{
static void RandomAccess(MyData data)
{
data.Data[1] = "this line is invalid if MyPropList return an IEnumerable<string>";
}
}
Я мог бы изменить свой интерфейс, чтобы потребовать реализацию IList (вариант 1), но это ограничивает, кто может реализовать интерфейс и количество классов, которые могут быть переданы в ConsumerA. Или я мог бы изменить реализацию (класс MyData), чтобы он возвращал IEnumerable вместо List (вариант 2), но затем нужно было бы переписать ConsumerB.
Это кажется недостатком С#, если кто-то не может просветить меня.