Изменение типа унаследованного свойства (на унаследованный тип) - PullRequest
8 голосов
/ 04 ноября 2011

с использованием C # У меня есть класс, который содержит среди других метаинформации корневой узел ориентированного графа. Давайте назовем это Контейнер-класс . Этот контейнер может отображаться в двух разных режимах: Режим редактора и Режим конфигуратора. В зависимости от режима корневой узел может иметь другой тип NodeEdit или NodeConfig , оба наследуются от одного и того же подкласса.

public abstract class NodeBase
{
  string Name { get; set; }
  ...
}

public class NodeEdit : NodeBase ...
public class NodeConfig : NodeBase ...

Для контейнера я также создаю базовый класс и наследую от него:

public abstract class ContainerBase
{
  NodeBase Root { get; set; }
  ...
}

При создании классов для Editor- и Configuratorcontainer путем наследования от ContainerBase я хочу стать типом Root-свойства определенного (унаследованного от NodeBase) типа, такого как:

public class ContainerEditor : ContainerBase
{
  NodeEditor Root { get; set; }
  ...
}

Но я не могу изменить тип свойства, определенного в ContainerBase. Есть ли способ решить эту проблему? Я могу использовать BaseNode-тип и добавить элемент NodeEditor, например

ContainerEditorInstance.Root = new NodeEditor();

, поскольку тип NodeEditor унаследован от типа BaseEditor, но в классе Container-Editor я хочу явно разрешить только типу Root-свойства быть NodeEditor . Я мог бы проверить это в установщике и отклонить все узлы, кроме узлов типа NodeEditor, но мне бы хотелось, чтобы свойство было определенного типа, чтобы я мог обнаруживать неправильные назначения во время компиляции.

Заранее спасибо,
Frank

Ответы [ 4 ]

12 голосов
/ 04 ноября 2011

Используйте дженерики:

public abstract class ContainerBase<T> where T:NodeBase
{
  T Root { get; set; }
  ...
}

public class ContainerEditor : ContainerBase<NodeEditor>
{      
  ...
}
5 голосов
/ 04 ноября 2011

Вы можете переопределить его:

public class ContainerEditor : ContainerBase
{
  public NodeEditor Root {
    get { return (NodeEditor)base.Root; }
    set { base.Root = value; }
  }
  ...
}
1 голос
/ 04 ноября 2011

Вы можете сделать базовую основу контейнера общей:

public abstract class ContainerBase<TRoot> where TRoot : NodeBase
{
  TRoot Root { get; set; }
  ...
}

В производном классе вы указываете тип:

public class ContainerEditor : ContainerBase<NodeEditor>
{
  ...
}
0 голосов
/ 04 ноября 2011

Полагаю, хорошим решением здесь будет Generics.Итак, вы бы написали что-то вроде этого:

public class ContainerEditor<T>:ContainerBase
{
    T Root {get;set;}
}
...