我一直在尝试解决没有基于方法参数类型的多态分派的 C#,并且我遇到过您无法传递类型。
我基本上有一个Model
实现两种方法的抽象类:IEnumerable<Decision> GetDecisions()
和void TakeDecision(Decision decision)
. Decision
也是一个抽象类。这个类的消费者反复获得可能的决定,评估它们并将最好的决定传回给Model
.
每个单独的派生模型都可以处理一些常见的决策和一些特定于模型的决策,并且我为每个特定类型可以使用的单独的TakeDecision()
方法。问题当然是单次调度。理想情况下,消费者会这样做:Decision
Model
var m = ModelFactory.GetModel(some parameters); //m is type Model
var ds = m.GetDecisions(); //ds is IEnumerable<Decision>
//Some logic here to choose the best Decision d
m.TakeDecision(d);
现在我必须在每个 derived 中实现看起来像这样的逻辑Model
,因为 C# 可以分派到正确的Model
实现,但不能分派到正确的重载:
if (decision is FooDecision) TakeDecision((FooDecision)decision);
if (decision is BarDecision) TakeDecision((BarDecision)decision);
...
或者我强迫消费者站在他们这边进行选角(他们很可能已经这样做了以检查决定)。
我想System.Type
在每个派生类中有一个 s 列表,所以我可以这样做:
foreach (var t in AllowedDecisionTypes) {
if (decision is t) TakeDecision((t)decision);
}
但它看起来System.Type
不是真正的类型:
- 你不能这样做:
AllowedDecisionTypes.Add(FooDecision)
,但你可以这样做AllowedDecisionTypes((new FooDecision()).GetType())
- 反之亦然,你不能做
decision is AllowedDecisionTypes[0]
,但你可以做decision is FooDecision
。
有没有办法两者兼得?即,生成类型列表并转换为它们?还是void Decision.ApplyTo(Model model) { model.TakeDecision(this); }
在每个决定上进行双重调度和实施的唯一方法,这可能应该调度到正确的重载,因为this
现在是特定的Decision
?