Я сталкиваюсь с ситуацией, когда у меня есть два уровня полиморфизма, один внутри другого, в иерархии родитель / потомок.
Я думаю, это лучше всего объяснить на простом примере:
class Group
{
public IList<Person> People { get; set; }
}
class SpecialGroup : Group
{
public IList<SpecialPerson> People { get; set; }
}
class Person {}
class SpecialPerson : Person {}
Таким образом, у Группы есть список объектов Person, тогда как у специализированной группы (SpecialGroup) есть специализированный список объектов Person (SpecialPerson).
Это компилируется, но я получаю предупреждение о том, что я должен использовать ключевое слово "new" в SpecialGroup.People, потому что оно скрывает свойство Group.People.
Я понимаю, что это значит, но, возможно, я не до конца понимаю, как вы могли бы правильно смоделировать что-то подобное в C # для начала. Любые мысли о том, как смоделировать это лучше?
Кроме того, есть идеи, как это будет играть с NHibernate? Я не уверен, что использование ключевого слова "new" обрежет его, поскольку свойство Group.People уже будет отображаться с другим типом. Есть ли лучший способ смоделировать это, совместимый с NH?
Хорошо, я подумал о том, как смоделировать это с помощью обобщений:
abstract class AbstractGroup<PersonType>
where PersonType : Person
{
public IList<PersonType> People { get; set; }
}
class Group : AbstractGroup<Person>
{}
class SpecialGroup : AbstractGroup<SpecialPerson>
{}
class Person {}
class SpecialPerson : Person {}
Я думаю, это делает то, что я хочу? Теперь Person может делиться чертами с SpecialPerson, но только SpecialPerson может быть добавлен в SpecialGroup. Базовый тип AbstractGroup может моделировать черты, общие для любой группы.
Теперь вопрос, взорвется ли NH, если я попытаюсь отобразить это?
Для записи, похоже, что некоторые люди успешно использовали запрос с универсальными классами - для запросов HQL (мой сценарий использования) это не поддерживается.
Другой подход, который пришел мне в голову, это просто скрыть реализацию родительского свойства, например используя ключевое слово "new" для переопределяющего свойства в подклассе - следующий поток обсуждает, почему это не будет работать:
NHibernate: отображение таблицы на подкласс и новое ключевое слово
Заключение на данный момент: проверка во время выполнения и исключения, как предложено @empi ниже.