У меня есть следующие 3 класса:
class Node {
public Node Parent;
// Edit: to clarify, each of these classes has many fields and methods
public void Method1() { /*...*/ }
public void Method2() { /*...*/ }
/* ... */
public void Method30() { /*...*/ }
}
class Element : Node { public Dictionary<string, string> Attributes; }
class Document : Element { }
Мне нужен способ определить ExtraNode
, ExtraElement
и ExtraDocument
, чтобы они были эквивалентны копированию кода выше,добавив несколько дополнительных полей к классу Node
и добавив к ним все классы с помощью «Extra», например:
class ExtraNode { public Node Parent; public int Priority; }
class ExtraElement : ExtraNode { public Dictionary<string, string> Attributes; }
class ExtraDocument : ExtraElement { }
Что лучше для этого добиться?Я думал об интерфейсах (ExtraNode : Node, IExtra
), но затем (ExtraElement is ExtraNode) == false
.
Я также думал о переписывании классов как обобщения (Node<T>, Element<T>, Document<T>
), а затем об их использовании для определения новых классов (ExtraNode : Node<MyExtraClass>
ии так далее), но это все равно приводит к проблеме (ExtraElement is ExtraNode) == false
, потому что (Element<MyExtraClass> is Node<MyExtraClass>) == false
.
Так каков наилучший способ достижения этого, без копирования / вставки всего документа и изменения вручную?Мне нужно будет сделать это несколько раз.
Редактировать: , чтобы уточнить, что мне нужно сделать, мне нужен следующий код для работы:
// this should accept an ExtraNode, an ExtraElement or an ExtraDocument:
void doSomethingWithANode(ExtraNode extraNode) { ... }
Edit 2: Предложение Кирка о реализации интерфейсов (на примере кода Тимви) нецелесообразно в моем случае, потому что у каждого класса есть много полей и методов (а всего около 8 классов), поэтому я хотел бынеобходимо скопировать каждый из них для каждой производной группы «Extra».Например, вот как должны выглядеть классы Node:
class INode {
INode Parent { get; }
void Method1();
void Method2();
/* ... */
void Method30();
}
class ExtraNode {
public int Priority { get; } // extra
public INode Parent { get; } // THIS IS WRONG, THIS SHOULD BE ExtraNode NOT INode
public void Method1() { ... } // here I have to define the entire method
public void Method2() { ... }
/* ... */
public void Method30() { ... }
}
class SuperNode {
public string Superpower { get; } // extra
public INode Parent { get; } // THIS IS WRONG, THIS SHOULD BE SuperNode NOT INode
public void Method1() { ... } // here I have to define the entire method AGAIN
public void Method2() { ... } // all methods are identical to the ones in ExtraNode
/* ... */
public void Method30() { ... } // this is unnecessary code duplication
}
Таким образом, каждый раз дублируется 30 методов.И это относится ко всем остальным классам.Этим методом я бы столько дублировал, что практически дублировал весь код.Было бы проще просто скопировать / вставить весь класс, переименовать и добавить к ним дополнительные поля.