2012-06-13 4 views
0

У меня есть иерархия классов (в .NET 3.5), как показано ниже:Изменение типа переменной во время выполнения

Parent 
    - Child1 
    - Child2 
    - Child3 

У меня есть базовый класс, как показано:

public abstract class BaseClass 
{ 
    protected Parent field; 

    public BaseClass(Parent someField) 
    { 
     this.field = someField 
    } 

    public string Property1 
    { 
     get { return field.Child1Property; } 
     set { field.Child1Property = value; } 
    } 
} 

Параметр, который я прохождение в конструкторе будет одним из детей. Есть ли способ доступа к свойствам Child с помощью переменной типа «Родитель»?

В качестве альтернативы, можно сделать это:

public abstract class BaseClass 
{ 
    protected Parent field; 
    protected Type childType; //Type? Or something else? 

    public BaseClass(Parent someField) 
    { 
     //assign the runtime type of someField to childType 
     this.field = someField 
    } 

    public string Property1 
    { 
     get { return ((childType)field).Child1Property; } //Is this possible? 
     set { ((childType)field).Child1Property = value; } 
    } 
} 

Если я использую тип это, кажется, не работает, поскольку (поле (childType)) .Child1Property не допускается. Проблема в том, что я только узнаю, какой тип ребенка передается во время выполнения, поэтому приведение поля к соответствующему типу не представляется возможным.

Помощь!

+0

как объект __dynamic__ HTTP://msdn.microsoft.com/en-us/library/dd264736.aspx – corn3lius

ответ

4

Вы можете сделать это:

public abstract class BaseClass 
{ 
    protected Parent field; 

    public BaseClass(Parent someField) 
    { 
     this.field = someField 
     if (someField is Child1) 
      this.Property1 = ((Child1)someField).Foo(); 
    } 

    public Int32 Property1 
    { 
     get { return field.Child1Property; } 
     set { field.Child1Property = value; } 
    } 
} 

Однако, есть один нюанс здесь. Вам необходимо указать , что экземпляр parent передается в тип Child1, или ничего не произойдет. В общем случае считается плохим дизайном, чтобы иметь if/then, который охватывает все возможные дочерние классы, потому что это означает, что когда вы добавите другого ребенка в будущем, вам нужно будет помнить, чтобы вернуться сюда и добавить его в if/then ,

Правильный способ сделать это на самом деле иметь свойство в Родитель, который переопределен в детстве:

public class Parent { 
    public virtual Int32 Foo() { return 5; } 
} 

public class Child1 : Parent { 
    public override Int32 Foo() { return 7; } 
} 

И затем использовать свойство:

public BaseClass(Parent someField) 
    { 
     this.field = someField 

     // If someField happens to be a Child1, this will be 7 
     this.Property1 = someField.Foo(); 
    } 
Смежные вопросы