在运行时更改变量类型

时间:2012-06-13 18:41:40

标签: c# .net

我有一个类层次结构(在.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; }
    }
}

我在构造函数中传递的参数将是其中一个Children。有没有办法通过父类型的变量访问子属性?

或者,是否可以这样做:

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; }
    }
}

如果我使用Type,它似乎无法工作,因为((childType)字段)。不允许使用.Child1Property。问题是,我只发现在运行时传递了什么类型的子节点,因此似乎不可能将字段转换为适当的类型。

帮助!

2 个答案:

答案 0 :(得分: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

执行此操作的正确方法是在Parent中具有一个属性,该属性在子节点中被覆盖:

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();
    }

答案 1 :(得分:2)

您可能希望使用Interfacegenerics