2011-11-04 38 views
8

usando C# Tengo una clase que contiene, entre otras metainformaciones, el nodo raíz de un gráfico dirigido. Llamemos esto al Container-Class. Este contenedor puede aparecer en dos modos diferentes, Editor-Mode y Configurator-Mode. Según el modo, el nodo raíz es de un tipo diferente NodeEdit o NodeConfig, ambos heredan de la misma subclase.Cambiar el tipo de una propiedad heredada (a un tipo heredado)

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

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

para el contenedor, también se crea una clase base y heredar de ella:

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

Al crear las clases de Editor-Configuratorcontainer y heredando de ContainerBase, que desea convertirse en el tipo de la raíz - la propiedad específica (heredado de NodeBase) tipo como:

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

Pero no puede cambiar el tipo de una propiedad definida en ContainerBase. ¿Hay alguna manera de resolver este problema? Puedo utilizar el tipo BaseNode, y añadir un elemento de NodeEditor como

ContainerEditorInstance.Root = new NodeEditor(); 

porque el NodeEditor tipo se hereda del tipo BaseEditor, pero en la clase Container-Editor, quiero permitir explícitamente sólo el tipo de la Root-property es NodeEditor. Podría verificar esto en el setter y rechazar todos los nodos excepto los de tipo NodeEditor, pero me gustaría que la propiedad sea del tipo específico, para poder detectar las asignaciones incorrectas en tiempo de compilación.

Gracias de antemano,
Frank

Respuesta

4

Usted puede redeclare que:

public class ContainerEditor : ContainerBase 
{ 
    public NodeEditor Root { 
    get { return (NodeEditor)base.Root; } 
    set { base.Root = value; } 
    } 
    ... 
} 
+0

Hola Marc, ¡gracias por la respuesta! Ya lo había intentado con redeclaración, pero probablemente hice algo mal. ¡Probé tu enfoque y funciona bien! En general, ¿hay situaciones en las que la redeclación debe preferirse a Genéricos o viceversa o son iguales? – Aaginor

+0

Todo este material genérico está causando problemas serios cuando la clase base genérica se debe usar, es decir, como un tipo de residuo abstracto.Así que le daré una oportunidad a la redeclación, ya que parece menos intrusiva. En comparación con 'nuevo' y 'sobrescribir', ¿cómo funciona la redeclaración internamente? ¿Hay algún buen artículo al respecto que puedas recomendar? ¡Gracias de nuevo! – Aaginor

9

Use genéricos:

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

public class ContainerEditor : ContainerBase<NodeEditor> 
{  
    ... 
} 
+0

Hola Blau, no tratado con los genéricos junto a la HashSet habitual y uso similar. ¡Piensa que este será un buen momento para trabajar con ellos! – Aaginor

1

Usted puede hacer la base del contenedor genérico:

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

En la clase derivada se especifica el tipo:

public class ContainerEditor : ContainerBase<NodeEditor> 
{ 
    ... 
} 
+0

Buena idea, voy a intentarlo. – Aaginor

0

Supongo que una buena solución aquí será Generics. Por lo que iba a escribir algo como esto:

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

Necesitaría declarar la raíz en el ContainerBase para poder acceder a ella en funciones que no necesitan saber si es el Editor o el Configurador. De todos modos, los genéricos suenan como una buena idea, como lo demostraron Guffa y Blau. – Aaginor

Cuestiones relacionadas