访问对象的属性而无需强制转换它

时间:2012-02-13 06:01:27

标签: c# oop inheritance

我有以下三个班级

public class Base
{
    string name;
}

public class Foo : Base
{
    int value;
}

public class Bar : Base
{
    double value;
}

这就是我正在尝试的

Base current = null;

if (somecondition)
    current = new Foo();
else
    current = new Bar();

for (int i=0; i<5; i++)
{
    current.value = i;           
}

问题是VS 2010在循环体中显示错误,因为Base没有属性value

现在,我可以通过这种方式解决这个问题:

Base current = null;
bool isBar = true;

if (somecondition)
{
    current = new Foo();
    isBar = false;
}
else
    current = new Bar();

for (int i=0; i<5; i++)
{
    if (isBar)
        (current as Bar).value = i;          
    else
        (current as Foo).value = i;
}

但是我希望有一个更好的解决方案,因为一旦循环开始迭代,current的类型不会改变,但我将测试类型并相应地为每次迭代投射它。 / p>

这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:2)

在使字段可访问(或将它们公开为可访问的属性)之后,您的选项是:

  • 使用抽象方法或属性来设置基类抽象,以设置值(并可能返回它) - 这里的问题是当两种类型不同时你不能轻易做到这一点
  • 创建一个界面来执行相同类型的操作,并转换为界面
  • 就像你现在一样
  • 如果您使用的是C#4,请使用dynamic - 只需将current声明为dynamic,然后您可以分配给current.value,编译器会插入代码来运行它在执行时间
  • 重新设计代码/继承层次结构

就我个人而言,我至少会考虑最后一种方法 - 这里的继承是否合适? value的两种类型真的需要不同吗?它们是否具有相同的含义,如果是这样,将值推送到基类并且如果需要不同类型可能使其成为通用的是有意义的吗?

答案 1 :(得分:0)

您可以代替使用基类创建一个将Value作为属性的接口,然后让Foo和Bar实现该接口。

答案 2 :(得分:0)

首先,您的“值”字段不会公开显示。

其次,我认为你不会在这里摆脱明确的投射。只是想象你的Bar类看起来像这样:

   public class Bar : Base
   {
    public string value;
   }