2014-02-10 182 views
0

我有以下代码:C#铸造

public class BaseClass {} 
public class Class1 : BaseClass {} 
public class Class2 : BaseClass {} 

public class BaseClassList : List<BaseClass> {} 
public class Class1List : List<Class1> {} 
public class Class2List : List<Class2> {} 

    public void Setup() 
    { 
     BaseClassList b = new BaseClassList(); 
     b.Add(new BaseClass()); 
     b.Add(new BaseClass()); 
     b.Add(new BaseClass()); 

     var list = from a in b 
        select a; 

     Class1List c1 = new Class1List(); 

     foreach (BaseClass a in b) 
     { 
      var o = a as Class1; 
      if (o != null) 
       c1.Add(o); 
     } 
    } 

然而,铸造为Class1的时候,邻始终为空。问题是什么?

+0

您只向'b'添加'BaseClass'并且没有'Class1'。每只狗都是动物,但不是所有的动物都是狗。 –

+0

http://stackoverflow.com/questions/10172767/cast-base-instance-to-derived-class-downcast-in-c-sharp –

+2

由于不会将一个类转换为另一个类,因此只会在它指定它的情况下是该类型的一个实例 – Liath

回答

5

问题是a不是Class1对象。就这样。 再次仔细阅读您的代码 - 您为什么会认为一个BaseClass对象可以被转移到一个类中,并从中派生出来?

3

becasue aBaseClass根据您的代码:

... 
b.Add(new BaseClass()); 
b.Add(new BaseClass()); 
b.Add(new BaseClass()); 
... 

,你可以不投基地孩子类,你必须这样做,反之亦然。

例子:

... 

    b.Add(new Class1()); 
    b.Add(new Class1()); 
    ... 

,并在此之后将是正确的:

foreach (var a in b) 
{ 
    var o = a as Class1;//CORRECT.  
} 
+3

所有Class1都是BaseClass,但并非所有BaseClass都是Class1 – Liath

0

因为你铸造你的基类的超类。 就像告诉编译器一个“Person”永远是“软件开发者”,它应该是相反的方式。所以,“软件开发者”永远是“人”,“会计师”也是“人”。

因此, “BaseClass”是“Person”; “Class1”是“软件开发人员”; “Class2”是“会计”

因此,您应该将“Software Developer/Class1”或“Accountant/Class2”的实例添加到BaseClassList的“Person”列表中。

然后将你的BassClass标记为抽象。