如何从基类列表中获取子类对象?

Naa*_*Hai 1 .net c# inheritance

我们考虑一个样本层次结构

class BaseClass{}

class ChildClass1 : BaseClass{}

class ChildClass2 : BaseClass{}
Run Code Online (Sandbox Code Playgroud)

现在我有一个BaseClass类型的通用列表

List<BaseClass> sampleList = new List<BaseClass>();
Run Code Online (Sandbox Code Playgroud)

在这个列表中,我添加了Both ChildClass1和的对象ChildClass2.

现在,当访问这些对象时,我想对不同类型的对象进行不同的操作.我可以轻松地使用if-else并检查对象是否是所需类型.

 class SampleClass
 {
     int Property{get;set;}
     List<BaseClass> sampleList = new List<BaseClass>();
     void DoCalculations()
     {
        foreach(var obj in sampleList)
        {
            if(obj is ChildClass1){//Do something to this.Property}
            else if(obj is ChildClass2){//Do Somethingto this.Property}
         }
     }
 }
Run Code Online (Sandbox Code Playgroud)

但是由于复杂性和性能问题,我想避免使用if-elseor switch(我的实际案例包含大量的派生类).

因此,为了解决这个问题,我想出了一种方法来重载具有相同名称但不同类型的方法(每种方法都适用于每种派生类型).

我想过以某种方式迭代并将BaseClass转换为ChlidClass对象并将其传递给DoSomething()方法,重载本身将负责执行哪个操作.但是,我无法从BaseClass获取ChildClass类型的对象以动态工作.

我试过的是:

class SampleClass
{
    int Property{get;set;}
    List<BaseClass> sampleList = new List<BaseClass>();

    public void DoCalculations()
    {
        foreach(var entry in sampleList)
        {
            Type type = entry.GetType();
            var obj = entry as type; //getting error here
            this.DoSomething(obj);
        }
    }

    private void DoSomething(ChildClass1 obj){//Do something to this.Property}

    private void DoSomething(ChildClass2 obj){//Do something to this.Property}
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我只展示了一个属性的使用int Property{get;set;},但在我的实际情况中考虑了多个属性.有没有办法实现我的需要?

编辑:正如下面的注释和几个答案中所提到的,在BaseClass()中使用DoSomething()并在ChildClasses中覆盖它们,这在我的情况下实际上可能不起作用,因为DoSomething()适用于类的全局字段属性.它定义于.它不是特定于ChildClass的对象.

Dom*_*nik 5

考虑制作你的课BaseClass abstract并给它一个abstract方法.这两种类型的ChildClass1ChildClass2将被迫重写DoSomething()

如果BaseClass由于某种原因你无法制作摘要,你也可以制作方法virtual,然后overrideChildClass1ChildClass2

抽象方法:

abstract class BaseClass
{    
    public abstract void DoSomething();
}

class ChildClass1 : BaseClass{
    public override void DoSomething()
    {
        Console.WriteLine("Impl. 1");
    }
}

class ChildClass2 : BaseClass{

    private string _someRandomAttribute = "Impl. 2";
    public override void DoSomething()
    {
        Console.WriteLine(_someRandomAttribute);
    }
}
Run Code Online (Sandbox Code Playgroud)

虚拟方法:

class BaseClass
{    
    public virtual void DoSomething()
    {
       Console.WriteLine("Base implementation for types that don't override DoSomething()");
    }
}

class ChildClass1 : BaseClass{
    public override void DoSomething()
    {
        Console.WriteLine("Impl. for type ChildClass1");
    }
}

class ChildClass2 : BaseClass{
    public override void DoSomething()
    {
        Console.WriteLine("Impl. for type ChildClass2");
    }
}
Run Code Online (Sandbox Code Playgroud)

完成后,您将能够执行以下操作:

foreach(var obj in sampleList)
{
    obj.DoSomething();
}
Run Code Online (Sandbox Code Playgroud)