假设我有一个名为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>();
接下来,让我们将一个Class1和Class2的实例添加到genericList。
genericList.Add(new Class1());
genericList.Add(new Class2());
现在,我有一个问题。如果我想访问Class1.IsGreen或Class2.IsPurple,我必须将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;
}
}
这只是你应该做的事情吗?这对我来说似乎非常笨重,而我正在编写的使用这种代码结构的代码的复杂性已经失控。我是继承人的新手,想要了解这是否就是你应该做的事情,或者是否有更好的选择。
答案 0 :(得分:2)
这实际上取决于你想要做什么。如果您可以抽象出属性,例如IsSelected
,那么您可以将它作为虚拟或抽象属性在BaseClass
上公开。然后你就不必在for-loop中投射你的物品了。
或者您可以将其抽象为抽象/虚拟方法,例如UpdateColor(bool)
。然后每个派生类都可以覆盖它并在它们自己上设置适当的属性。
还有其他几种选择,包括接口和扩展方法,您可以使用它们使其更清洁。
答案 1 :(得分:1)
基本上没有更好的选择,但如果您只想操作,比如说Class1
,那么您可以使用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;
}
答案 2 :(得分:1)
如果你能以某种方式abstarct在循环中做什么,例如,你正在为一个项目应用默认颜色,所以公开方法IEntity.SetDefaultColors(IColorInformation)
并在每个项目类中实现它。
BTW:考虑Interface segregation principle并为IEntity
等实体引入一个通用界面。
答案 3 :(得分:0)
我会说这样的话, 伪代码! :
public sbstract 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();
}
应该工作..
问候。
答案 4 :(得分:0)
为了更好(或更糟)地说明,我将把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。
您可以阅读有关旗帜的更多信息(并确定它们是否适用于您的情况)at this link。
我也推荐this SO question。特别是最高投票(虽然不被接受)的答案。