把两个不同的类和同一个基类放在同一个列表中的更好的方法

本文关键字:同一个 基类 列表 方法 更好 两个 | 更新日期: 2023-09-27 18:03:27

假设我有一个名为BaseClass的基类:

public BaseClase{
    public bool isCool;
}

现在假设我有两个类继承自BaseClass

public Class1: BaseClass{
    public bool isGreen;
}
public Class2: BaseClass{
    public bool isPurple;
}

现在假设我想通过创建list创建一个包含Class1和Class2实例的列表;

var genericList = new List<BaseClass>();

接下来,让我们向genericList中添加Class1和Class2的实例。

genericList.Add(new Class1());
genericList.Add(new Class2());

现在,我有一个问题。如果我想进入Class1。是绿色还是Class2。如果是紫色,我必须将genericList中的每个项强制转换为Class1或Class2。

foreach(var item in genericList){
    if(item is Class1){
        var temp = (Class1) item;
        temp.IsGreen = true;
    }
    if(item is Class2){
        var temp = (Class2) item;
        item.IsPurple = true;
    }
}

这就是你应该做的事情吗?对我来说,这似乎非常笨拙,而且我正在编写的使用这种代码结构的代码的复杂性已经超出了控制范围。我是继承的新手,想知道这是否就是你应该做的事情,或者是否有更好的选择。

把两个不同的类和同一个基类放在同一个列表中的更好的方法

这取决于你想做什么。如果你可以抽象出属性,比如IsSelected,那么你可以在BaseClass上公开它作为虚拟或抽象属性。这样就不必在for循环中强制转换项了。

或者您可以将其抽象为抽象/虚拟方法,如UpdateColor(bool)。然后,每个派生类都可以重写该属性,并为自己设置相应的属性。

还有一些其他的选择,包括接口和扩展方法,您可以使用它们来使它更干净。

基本上没有更好的选择,虽然如果你只想操作,说Class1 's,那么你可以使用OfType扩展

var genericList = new List<BaseClass>();
genericList.Add(new Class1());
genericList.Add(new Class2());
foreach(var item in genericList.OfType<Class1>())
{
  // no need to cast
  item.IsGreen = true;
}

如果你可以抽象出你在循环中所做的事情,例如,你正在为一个项目应用默认颜色,那么暴露IEntity.SetDefaultColors(IColorInformation)方法并在每个项目类中实现它。

顺便说一句:考虑接口隔离原则,并为您的实体(如IEntity)引入一个公共接口。

为了更好(或更糟)地说明,我将把IsGreen更改为IsSpecial,将IsPurple更改为MaximumHappiness——这样我们就可以清楚地看到这两个属性代表两种截然不同的东西。

处理它的一种方法是使它们都是基类的属性(如果适用的话),这样就不必对它们进行类型转换。 另一种方法是为基类提供一个函数(继承类可以覆盖它)。例如,这个函数可以被称为"DoSpecialThing",在它里面你可以访问子类的任何属性。

如果属性保证为布尔值(并表示一些相关的想法),那么您可能可以使用标志。例如:

[Flags]
enum MoodType
{
    //Moods
    Happy,
    Sad,
    Elated,
    Overjoyed,
    Depressed,
    //Mental States
    Confused,
    Alert,
    Sluggish,
    //Other
    Sleepy,
    Awake
}

那么现在基类可以有一个名为"State"的属性或者其他什么,它可以是上述标志的任意组合。所以你可以在一个属性中指明一个对象是Sleepy, Confused和Happy。

你可以在这个链接中阅读更多关于标志的信息(并决定它们是否适用于你的情况)。

我也推荐这个SO问题。特别是票数最高(尽管未被接受)的答案

我会这样说,伪代码!:

public abstract BaseClase{
    public bool isCool;
    public abstract setColor();
}
public Class1: BaseClass{
    public bool isGreen;
    public override void SetColor() {IsGreen=true;}
}
public Class2: BaseClass{
    public bool isPurple;
    public override void SetColor() {IsPurple =true;}
}
foreach(var item in genericList){
    item.SetColor();
}

应该. .

问候。