0

我一直在尝试解决没有基于方法参数类型的多态分派的 C#,并且我遇到过您无法传递类型。

我基本上有一个Model实现两种方法的抽象类:IEnumerable<Decision> GetDecisions()void TakeDecision(Decision decision). Decision也是一个抽象类。这个类的消费者反复获得可能的决定,评估它们并将最好的决定传回给Model.

每个单独的派生模型都可以处理一些常见的决策和一些特定于模型的决策,并且我为每个特定类型可以使用的单独的TakeDecision()方法。问题当然是单次调度。理想情况下,消费者会这样做:DecisionModel

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不是真正的类型:

  1. 你不能这样做:AllowedDecisionTypes.Add(FooDecision),但你可以这样做AllowedDecisionTypes((new FooDecision()).GetType())
  2. 反之亦然,你不能做decision is AllowedDecisionTypes[0],但你可以做decision is FooDecision

有没有办法两者兼得?即,生成类型列表并转换为它们?还是void Decision.ApplyTo(Model model) { model.TakeDecision(this); }在每个决定上进行双重调度和实施的唯一方法,这可能应该调度到正确的重载,因为this现在是特定的Decision

4

2 回答 2

0

要将 a 添加Type到对象列表中,Type您只需使用typeof运算符而不是仅添加类型。

is对于一个对象的等效操作Type是使用它的IsAssignableFrom方法。

您将无法基于Type;投射对象 基于 a 调用多个重载之一的方法Type是通过反射。

于 2014-12-08T15:26:01.750 回答
0

Type是描述某种类型的对象,但如果我们这样看,它不是类型本身:String != typeof(String).

你可以做的是:

// Add type to collection of Type
AllowedDecisionTypes.Add(typeof(FooDecision))

// Check if the current decision EXACTLY of the same type
if(myDecision.GetType() == AllowedDecisionTypes[0])

// Check if the current decision inherits/implements that type (like using the 'is' operator)
if(AllowedDecisionTypes[0].IsAssignableFrom(myDecision.GetType()))
于 2014-12-08T15:28:29.007 回答