无需强制转换即可访问对象的属性

本文关键字:访问 对象 属性 转换 | 更新日期: 2023-09-27 18:24:21

我有以下三个类

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的类型就不会改变,但我将测试该类型,并相应地为每次迭代强制转换它。

做这件事的正确方法是什么?

无需强制转换即可访问对象的属性

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

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

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

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

首先,您的"value"字段不会公开为公共字段。

第二,我不认为你会摆脱这里明确的选角。只是想象一下你的酒吧类是这样的:

   public class Bar : Base
   {
    public string value;
   }