У меня есть ситуация, когда у меня есть IEnumerable, который мне нужен для повторения и выполнения некоторого кода для каждого элемента.Полиморфное расширение для сторонних классов
Этот код, который должен выполняться, зависит от фактического типа элемента, и то, что я ищу, является хорошим чистым способом сделать это без каких-либо условностей, поэтому, если количество производных типов, которые мне нужно обрабатывать, увеличивается. I просто нужно написать новый обработчик и не изменять какой-либо из моего существующего кода.
Чтобы проиллюстрировать это, я имею пример, где третья библиотека сторона содержит следующий код:
public abstract class BaseObject{ }
public class Derived1: BaseObject { }
public class Derived2 : BaseObject { }
и мой местный код делает что-то вроде:
void Execute(IEnumerable<BaseObject> list)
{
foreach (var item in list)
item.DoWork();
}
Я попытался создать методы расширения для этого:
public static class Extensions
{
public static int DoWork(this BaseObject obj) { return 0; }
public static int DoWork(this Derived1 obj) { return 1; }
public static int DoWork(this Derived2 obj) { return 2; }
}
, который, очевидно, не работает, поскольку каждый элемент в перечислении имеет тип BaseObject, поэтому всегда используется метод расширения, который возвращает 0.
У меня есть возможность создания нового производный типа для каждого производного типа всех реализации интерфейса:
public class MyDerived1: Derived1, IMyInterface
{
public int DoWork(){return 1;}
}
public class MyDerived2: Derived2, IMyInterface
{
public int DoWork(){return 2;}
}
public interface IMyInterface
{
int DoWork();
}
тогда я мог бы итерацию и приведение к новому интерфейсу:
void Execute(IEnumerable<BaseObject> list)
{
foreach (var item in list)
{
var local = item as IMyInterface;
local?.DoWork();
}
}
, но для этого требуется построение моего производного типа, и решение о том, какой тип для построения все еще требует условного утверждения, которое необходимо изменить для любого новый тип добавлен.
Очевидно, что использование фабричного шаблона здесь и его самое чистое решение, которое у меня есть до сих пор.
Паттерн команда предлагает решение, но в качестве команды для выполнения зависит от типа производного типа, условное по-прежнему необходимо, чтобы построить эту команду ...
Можно ли предложить такой подход, который бы полностью устранить любые условные условия, которые нуждаются в изменении при добавлении новых производных типов в микс?
Вы можете создать словарь при запуске, с помощью отражения, что позволило бы вашему заводу построить право производного типа без необходимости какого-либо условного, и карта будет автоматически включать любые новые производные типы, которые были добавлены без необходимости модификации , – Baldrick
благодарит @Baldrick, это подход, взятый в ответе в этом посте http://stackoverflow.com/questions/27724130/simulate-inheritance-by-extension. Честно говоря, я старался избегать размышлений. – MikeW
Я не уверен, что это возможно. Необходимая информация о базовом типе объекта BaseObject не может быть показана программно без: (a) виртуального метода вызывает сам объект для переопределенного метода (но он является сторонним и не может быть изменен) или (b), отражающие, затем используя условные обозначения. Не уверен, что в вашей ситуации есть другой путь. – Baldrick