Список записей соответствует как классу, так и интерфейсу?
У меня есть следующие классы и интерфейсы C#:
class NativeTool
class NativeWidget: NativeTool
class NativeGadget: NativeTool
// above classes defined by the API I am using. Below classes and interfaces defined by me.
interface ITool
interface IWidget: ITool
interface IGadget: ITool
class MyTool: NativeTool, ITool
class MyWidget: NativeWidget, IWidget
class MyGadget: NativeGadget, IGadget
Теперь я хотел бы, чтобы MyTool вел список детей. Все дети будут соответствовать ITool и наследоваться от NativeTool. Классы MyTool, MyWidget и MyGadget все соответствуют этим критериям.
У меня вопрос, есть ли способ сказать MyTool, что его дети всегда будут наследовать как от NativeTool, так и от ITool? Я могу сделать одно или другое достаточно легко. Но оба?
2 ответа
Решение
Это, кажется, сделать это. Раздражающее количество обёрток, но оно выполняет свою работу, не дублируя хранилище.
public interface ITool { }
public interface IWidget : ITool { }
public class NativeTool { }
public class NativeWidget : NativeTool { }
public class MyTool : NativeTool, ITool, INativeTool {
public MyTool() {
this.Children = new List<INativeTool>();
}
public ITool InterfacePayload { get { return this; } }
public NativeTool NativePayload { get { return this; } }
public List<INativeTool> Children { get; set; }
public NativeTool NativeChild(int index) {
return this.Children[index].NativePayload;
}
public ITool InterfaceChild(int index) {
return this.Children[index].InterfacePayload;
}
public void AddChild(MyTool child) {
this.Children.Add(child);
}
public void AddChild(MyWidget child) {
this.Children.Add(child);
}
}
public class MyWidget : NativeWidget, IWidget, INativeTool {
public ITool InterfacePayload { get { return this; } }
public NativeTool NativePayload { get { return this; } }
}
public interface INativeTool {
// the two payloads are expected to be the same object. However, the interface cannot enforce this.
NativeTool NativePayload { get; }
ITool InterfacePayload { get; }
}
public class ToolChild<TPayload>: INativeTool where TPayload : NativeTool, ITool, INativeTool {
public TPayload Payload { get; set; }
public NativeTool NativePayload {
get {return this.Payload;}
}
public ITool InterfacePayload {
get { return this.Payload; }
}
}
Вы можете сделать что-то вроде:
public class MyTool<T,U> where T: ITool where U: NativeTool
{
}
и создайте это как:
var tool = new MyTool<MyWidget, MyWidget>();
а также производные, как
public class MyWidget : MyTool<....>
{
}