C#: System.Type не является реальным типом? или: работа вокруг одной отправки

Я пытался обойти 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);

Теперь я должен реализовать логику, которая выглядит так в каждом производном Modelпотому что C# может отправлять на правильный Model реализация, но не до правильной перегрузки:

if (decision is FooDecision) TakeDecision((FooDecision)decision); if (decision is BarDecision) TakeDecision((BarDecision)decision); ...

или я заставляю потребителя выполнять кастинг на своей стороне (скорее всего, он уже сделал это, чтобы изучить решение).

Я хотел бы иметь список System.Types в каждом производном классе, поэтому я мог бы сделать это:

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?

2 ответа

Чтобы добавить Type к списку Type объекты, которые вам просто нужно использовать typeof оператор вместо простого добавления типа.

Эквивалентная операция is для Type объекты должны использовать его IsAssignableFrom метод.

Вы не сможете разыграть объект на основе Type; способ вызова одной из нескольких перегрузок на основе Type через отражение.

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()))
Другие вопросы по тегам