У меня есть доступ к структуре классов, которую я не могу изменить, следующим образом:
Graphics
Circle
Line
etc.
Опять же, я не могу изменить это! Все они имеют индивидуальные свойства, такие как Radius
, FirstPoint
, LastPoint
и т. Д., А также некоторые общие свойства.
Я хочу создать метод, который принимает объект Graphics
и, в зависимости от типа объекта, будет запускать метод ToJson
:
Graphics g = db.GetGraphic(123);
// Console.WriteLine(g.GetType()) prints "Circle"
// Should run some specific implementation for `Circle` type graphics, and
// have an overload for all types including Graphics
ToJson(g);
Сначала я подумал, что могу хитро перегрузить метод ToJson
:
ToJson(Graphics g) { ... }
ToJson(Circle g) { ... }
ToJson(Line g) { ... }
однако это, разумеется, касается общей перегрузки ToJson(Graphics)
каждый раз.
Я уверен, что мог бы сделать что-то вроде следующего:
if (g is Circle) ...
if (g is Line) ...
if (g is Graphics) ...
или создайте словарь, чтобы уменьшить сложность для каждого типа, но это не самый лучший способ сделать что-либо
Что я рассмотрел
Я подумал, есть ли какой-нибудь универсальный метод-обертка, который я мог бы использовать вокруг каждого объекта (например, new JsonGraphics(g).ToJson()
), но я не хочу выполнять какую-либо ручную проверку типа самостоятельно.
Я посмотрел на шаблон двойной отправки и посетителя, но я не был уверен, что они удовлетворяют моим требованиям, поскольку они выглядят так, как будто я должен изменить эти классы (или, может быть, я просто не до конца их понял), и (вроде очевидно, однако) дженерики также в основном находятся за окном, поскольку требуют, чтобы я заранее знал, что это за тип Graphics
.
Два вопроса:
Есть ли лучший способ сделать это, кроме как использовать какой-нибудь словарь или что-то другое if (g is Type)
-подобное?
Если бы я мог изменить классы, как бы выглядел шаблон? В этом случае это невозможно, но лучше ли использовать двойную рассылку / посетителя в случае, если я могу?