2010-06-30 32 views
1

一个简单的问题投对象...如何从一个数组

我有一个抽象类,细胞和两个类BorderCell和BoardCell,从细胞类继承。然后我有一个Cell []类型的Cells数组,其中包含BorderCell和BoardCell类型的对象。

abstract class Cell 
{ 
} 
class BorderCell : Cell 
{ 
    public void Method1(){}; 
} 
class BoardCell: Cell 
{ 
    public void Method2(){}; 
} 

... 

Cell[] Cells = new Cell[x]; 
for (int i = 0; i < x; i++){ 
    Cells[i] = new BorderCell(); 
    // or 
    Cells[i] = new BoardCell(); 
} 

现在我想将电池转换为BorderCell和运行其方法1,像这样:

(Border)Cells[i].Method1(); 

但是,这是不行的,我必须使用:

BorderCell borderCell = (BorderCell)Cells[i]; 
borderCell.Method1(); 

这是唯一(和正确的方式)做到这一点)?

+1

我会在这里回顾一下你的设计 - 不得不抛弃到派生类是一种糟糕的设计气味 - 如果你将它们保存在同一个集合中作为基类型,我期望它们是真正的多态(Liskov原理)。 – 2010-06-30 09:32:17

+0

Herbie博士:我很乐意提供建议,查看此主题:http://stackoverflow.com/questions/3140281/what-data-structure-to-use-in-my-example – sventevit 2010-06-30 09:47:54

回答

7

没有,你只需要支架让你想投适用于清楚什么:“”

((Border)Cells[i]).Method1(); 

基本上结合比铸铁更严格,所以你的原始代码:

(Border)Cells[i].Method1(); 

等同于:

(Border) (Cells[i].Method1()); 
+0

Jon今天很快就触发了(照常)! – Noldorin 2010-06-30 09:28:33

+0

我知道我错过了一些明显的... – sventevit 2010-06-30 09:52:02

4

尝试:

((BorderCell)Cells[i]).Method1(); 

括号,如果你用的铸造用它们提供类型界限。你的第一次尝试没有包装Cell [i]。

3

当你写

(BorderCell)Cells[i].method1(); 

投适用于表达Cells[i].method1();,这显然不会因为Cells[i]工作仍然返回Cell

如果你想腾出一个额外的变量,然后写:

((BorderCell)Cells[i]).method1(); 
2

既然你把2种(BorderCell和BoardCell)的细胞在数组中。我建议在投射前先检查类型。

if (Cells[i] is BorderCell) 
{ 
// cast to BorderCell 
} 
else 
{ 
// cast to BoardCell 
} 
+0

这取决于。如果代码知道应该在哪里存在BorderCells,那么有信心的是,如果它是错误的类型,那就表示一个bug,那么演员阵容是正确的做法。 – 2010-06-30 09:37:55

+0

诚然,商业逻辑坚持认为,如果一个单元格处于特定的位置,那么它应该有正确的类型。请参阅:http://stackoverflow.com/questions/3140281/what-data-structure-to-use-in-my-example – sventevit 2010-06-30 09:49:42