简体   繁体   English

C#创建一个List以保存基类的任何派生子级

[英]C# Make a List to hold any derived children of a base class

So I wish to setup an abstract base class to derive children classes from. 所以我希望设置一个抽象基类来从中派生子类。 All the work will take place on the children, but I wanted the children to be able to reference each other. 所有工作都将在孩子们身上进行,但我希望孩子能够互相参考。

Here is some pseudo-code: 这是一些伪代码:

public abstract class BaseClass<T> : SomeOtherClass {

    public List<BaseClass> listOfChildren;

    protected T thisChild;

    public void DoMoreStuff(){
        Debug.Log("Doing more stuff");
    }

    protected virtual void DoSomething(int i){
        listOfChildren[i].DoMoreStuff();
    }
}

public class FirstChildClass : BaseClass<FirstChildClass> {

    FirstChildClass<T>(){
        thisChild = this;
    }

    public void FirstClassStuff(){
        Debug.Log("first class stuff");
    }

}
public class SecondChildClass : BaseClass<SecondChildClass> {

    public void SecondClassStuff(){
        Debug.Log("second class stuff");
    }
}

How would I make a generic List to accept any child class? 如何使通用List接受任何子类?

Will I need to typecast listOfChildren with T to use DoMoreStuff()? 我是否需要使用T对listOfChildren进行类型转换才能使用DoMoreStuff()?

On its own, is there anything else inherently wrong with this setup? 就其本身而言,此设置还存在其他任何错误吗?

I think you overcompicate the solution. 我认为你过度合成了解决方案。 If you don't want to store any data in each node - try to solve this problem then without the generics. 如果您不想在每个节点中存储任何数据 - 尝试在没有泛型的情况下解决此问题。 I will give you a naive straight-forward implementation of desired behavior as a starting point. 我将以天真直接的方式实现所需行为作为起点。

public abstract class BaseClass  {

    private IList<BaseClass> children = new List<BaseClass>();

    public void AddChild(BaseClass child)
    {
        this.children.Add(child);
    }

    protected virtual void DoMoreStuff(){
        Debug.Write("Doing more stuff");
    }

    public void DoSomething(int i){
        children[i].DoMoreStuff();
    }
}

public class FirstChildClass : BaseClass {

    protected override void DoMoreStuff(){
        Debug.Write("first class more stuff");
    }

}

public class SecondChildClass : BaseClass {

    protected override void DoMoreStuff(){
        Debug.Write("second class more stuff");
    }
}

now you can 现在你可以

var root = new FirstChildClass();

root.AddChild(new FirstChildClass());
root.AddChild(new SecondChildClass());
root.AddChild(new FirstChildClass());

root.DoSomething(1); //will print second class more stuff
root.DoSomething(0); //will print first class more stuff

You need to separate between child classes and child data . 您需要将子和子数据分开。 A child class simply inherits from its parent, to provide a more detailed structure to the data (such as Animal and Dog ). 子类只是从其父类继承,为数据提供更详细的结构(例如AnimalDog )。 A child data, on the other hand, means that whatever the data represents is related to each other (such as Receipt and ReceiptLineItem ). 另一方面,子数据意味着数据表示的任何内容彼此相关(例如ReceiptReceiptLineItem )。

Normally, the two don't overlap. 通常,两者不重叠。 The Receipt class looks nothing like the ReceiptLineItem class, and the Receipt and a ExternalPurchaseOrder have nothing to do with each other, even though they both inherit their structure from Purchase . Receipt类看起来与ReceiptLineItem类不同, ReceiptExternalPurchaseOrder彼此无关,即使它们都从Purchase继承了它们的结构。 When they do overlap, you have a tree structure. 当它们重叠时,你有一个树形结构。 A Product may be composed of more Product s, which each may be composed of yet more Product s. Product可以由更多的Product S,其中每个可以由还更的Product号第


Here's how I'd rewrite your code, assuming you're looking for the first type of inheritance (class structure): 以下是我重写代码的方法,假设您正在寻找第一种类型的继承(类结构):

public abstract class BaseClass : SomeOtherClass {

    public static List<BaseClass> listOfChildren = new List<BaseClass>();

    public void DoMoreStuff(){
        Debug.Log("Doing more stuff");
    }

    protected virtual void DoSomething(int i){
        listOfChildren[i].DoMoreStuff();
    }
}

public class FirstChildClass : BaseClass {

    FirstChildClass(){
       // Set some things unique to this class
    }

    public void FirstClassStuff(){
        Debug.Log("first class stuff");
    }

}
public class SecondChildClass : BaseClass<SecondChildClass> {

    public void SecondClassStuff(){
        Debug.Log("second class stuff");
    }
}

You could then access the master list as BaseClass.listOfChildren . 然后,您可以访问主列表作为BaseClass.listOfChildren If you want all children to automatically register themselves, you can add that to the BaseClass constructor: 如果您希望所有子项自动注册,您可以将其添加到BaseClass构造函数:

protected BaseClass()
{
   listOfChildren.Add(this);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM