У меня есть предложенная схема элемента словаря, которая выглядит следующим образом:
public interface IDataDictionary
{
List<IDataDictionaryItem> DictionaryItems { get; set; }
}
И элементы словаря как:
public interface IDataDictionaryItem
{
Guid Guild { get; set; }
int SequenceId { get; set; }
string Title { get; set; }
string Value { get; set; }
string Description { get; set; }
string Language { get; set; }
}
Когда я пытаюсь реализовать это в конкретном классе, например:
public class HairColorDictionary : IDataDictionary
{
public List<HairColor> DictionaryItems { get; set; }
}
С пунктами конкретной реализации:
public class HairColor : IDataDictionaryItem
{
public Guid Guild { get; set; }
public int SequenceId { get; set; }
public string Title { get; set; }
public string Value { get; set; }
public string Description { get; set; }
public string Language { get; set; }
}
Я получаю сообщение об ошибке ниже, и я не могу обернуться вокруг него. Может кто-нибудь, пожалуйста, просветите меня, где это пошло не так.
Сообщение об ошибке:
Ошибка CS0738 "HairColorDictionary" не реализует элемент интерфейса "IDataDictionary.DictionaryItems". "HairColorDictionary.DictionaryItems" не может реализовать "IDataDictionary.DictionaryItems", поскольку у него нет соответствующего возвращаемого типа "List".
Я понимаю, к чему вы стремитесь, и причина, по которой он не работает, заключается в том, что интерфейс определил коллекцию, которая не является специфической (этот интерфейс может быть реализован), но вы пытаетесь реализовать этот элемент интерфейса в определенном путь.
Если вы действительно должны это сделать, вы можете сделать это с помощью дженериков. Вот обновленные биты:
public interface IDataDictionary<T> where T : IDataDictionaryItem
{
List<T> DictionaryItems { get; set; }
}
public class HairColorDictionary : IDataDictionary<HairColor>
{
public List<HairColor> DictionaryItems { get; set; }
}
T
позволяет вам использовать что угодно, а часть where T:...
накладывает на это ограничение.
Пожалуйста, поймите, что это потенциальный ответ на ваше решение. Я не нашел время, чтобы обдумать его достоинства или недостатки.
В вашей реализации HairColorDictionary
is-a
IDataDictionary
. Так что я мог бы сделать что-то плохое, как:
IDataDictionary d = new HairColorDictionary();
d.DictionaryItems.add(blah);
Здесь метод add ожидает что-то типа IDataDictionaryItem
и не обязательно HairColor
потому что d
это просто IDataDictionary
а не HairColorDictionary
! Так что я мог бы сделать что-то вроде
class SkinColor : IDataDictionaryItem { ... }
IDataDictionaryItem s = new SkinColor();
d.DictionaryItems.add(s);
Вопрос в том, действительно ли это последнее утверждение или нет? Он должен быть действительным, потому что add
ожидает IDataDictionaryItem
который SkinColor
правильно реализует. Но тогда это не должно быть действительным, потому что фактический public List<HairColor> DictionaryItems
допускает только HairColor
а не SkinColor
s !!!
Чтобы устранить эту путаницу и обеспечить строгую безопасность типов, вы должны следовать правилам ковариации и контравариантности. Или вы можете продолжить с @TheMuffinMan хорошим ответом.