C# 两种不同类型的进程列表

C# 两种不同类型的进程列表,c#,inheritance,C#,Inheritance,我有两种类型/类别导弹和跟踪导弹。其中跟踪导弹:导弹和跟踪导弹覆盖其基本更新方法 导弹更新实施如下: void Update() 而我希望跟踪导弹类型有一个额外的参数 void更新(矢量2目标) 然后我想要一个带有列表的导弹集合。若这是Typescript,我将使用联合类型实现它,并在迭代期间进行一些模式匹配 基本上针对这个无效代码: List=新列表{ 新导弹(……), 新型跟踪导弹(…) }; foreach(导弹中的var导弹){ 如果(导弹是导弹)导弹。更新() 否则如果(导弹正在跟

我有两种类型/类别
导弹
跟踪导弹
。其中
跟踪导弹:导弹
跟踪导弹
覆盖其基本
更新
方法

导弹
更新
实施如下:

void Update()
而我希望跟踪导弹类型有一个额外的参数

void更新(矢量2目标)
然后我想要一个带有
列表的导弹集合。若这是Typescript,我将使用联合类型实现它,并在迭代期间进行一些模式匹配

基本上针对这个无效代码:

List=新列表{
新导弹(……),
新型跟踪导弹(…)
};
foreach(导弹中的var导弹){
如果(导弹是导弹)导弹。更新()
否则如果(导弹正在跟踪导弹)导弹。更新(目标)
}
这里似乎是
跟踪导弹
不知何故被扔到了什么地方。我可以做的一个方法是两个实现两个不同类型的列表,但这是需要的,因为当我想要实现更多的
导弹派生时,它是不可维护的

tldr:我可以维护不同类型的集合,并在迭代过程中根据它们的类型运行不同的逻辑的最佳方式是什么。

您使用的是c#7.0或更高版本

List=新列表{
新导弹(……),
新型跟踪导弹(…)
};
foreach(导弹中的var导弹){
if(导弹正在跟踪导弹tm){
商标更新(目标);
}否则{
导弹更新();
}
}
我建议对所有导弹等级使用相同的接口:

 public class Missile {
   ...
   // In case of untracking missile we ignore its target
   public virtual void Update(Vector2 target) 
     => Update();

   // No target: just moving forward
   protected void Update() {...}
 }

 public class TrackingMissile : Missile { 
   ...
   // In case of tracking missile we put target into account 
   public override void Update(Vector2 target) {...}       
 } 
通过这样做,您可以轻松创建新的导弹类型,而无需更改
foreach
逻辑

 public class GuidedMissile : TrackingMissile { 
   ...
   public override void Update(Vector2 target) {
     // If target has been captured by radar
     if (IsTargetCaptured(target)) 
       base.Update(target); // ... approach to the target, 
     else 
       Update();            // otherwise just move forward
   }
 } 
这样你就可以

List<Missile> missiles = new List<Missile> {
  new Missile(...),
  new TrackingMissile(...),
  new GuidedMissile(...)
};

// Whatever missiles launched, update their locations
foreach (var missile in missiles)   
  missile.Update(target);
List=新列表{
新导弹(……),
新型跟踪导弹(…),
新指南许可证(…)
};
//无论发射什么导弹,都要更新它们的位置
foreach(导弹中的var导弹)
导弹。更新(目标);

如果(导弹正在跟踪导弹tm)tm.Update(目标);else.Update()--将更具体的类型放在第一位,因为两者都是导弹。还可以将Update()设为虚拟,并为其指定一个目标参数,该参数在不需要时不使用。或者让跟踪导弹跟踪自己的目标是有意义的,而不是将其作为参数传递。如果更改
if/else
的顺序会怎么样<代码>如果(导弹正在跟踪导弹)导弹。更新(目标);否则,如果(导弹是导弹)导弹。更新()
您可以使用<代码>如果(导弹正在跟踪导弹tm)tm.更新(目标);else.Update()
为什么不为
导弹执行
无效更新(矢量2目标)
,而忽略
目标
,当它不是
跟踪导弹时?@DmitryBychenko虽然这是一个糟糕的做法,因为基地导弹不需要
目标
非常有趣,我最初的想法是正确的,看起来顺序很重要,确保它不总是属于它的基类
List<Missile> missiles = new List<Missile> {
  new Missile(...),
  new TrackingMissile(...),
  new GuidedMissile(...)
};

// Whatever missiles launched, update their locations
foreach (var missile in missiles)   
  missile.Update(target);