![](/img/trans.png)
[英]How to force implementation of an abstract classes members in the inheriting class?
[英]Force classes to contain/use their own specific implementation of an abstract class
我正在用C#开发一个TUI库,我需要有关如何为显示对象做颜色主题的建议。 可以在屏幕上绘制的对象都从此接口继承:
public interface IDrawable
{
Area ScreenArea { get; }
List<char[]> DisplayChars { get; }
//some other properties...
}
或者更确切地说,更具体地,对于每个绘制对象的接口实现此接口( IWindow
是IDrawable
)。 每个IDrawable
都绘制在由Area结构体表示的控制台窗口的指定部分上:
public struct Area
{
public readonly int EndX;
public readonly int EndY;
public readonly int Height;
public readonly int StartX;
public readonly int StartY;
public readonly int Width;
public Area(int startX, int endX, int startY, int endY)
{
StartX = startX;
EndX = endX;
StartY = startY;
EndY = endY;
Height = endY - startY;
Width = endX - startX;
}
/// <summary>
/// Get the overlapping area between this area and another.
/// </summary>
/// <param name="refArea"></param>
/// <returns>Overlap area relative to the upper left corner of the ref area.</returns>
public Area OverlapWith(Area refArea)
{
//....
}
}
对象的实际绘制由静态Display
类中的方法处理,该类在DisplayChars中的每个元素上调用Console.Write()
。 我希望从IDrawable
继承的每个类被强制实现自己的规则,如何将其区域划分为单独的颜色区域,例如,弹出窗口可能具有用于其外边界的单独可着色区域,其标题(在它的外边界)和它的内部区域。
我一直在讨论如何做到这一点。 我需要创建一个类型ColorScheme
,以包含用什么颜色写入哪些字符的规则。 我决定最好的方法是将它作为一个抽象类,它包含一个“子区域”列表,颜色可以单独应用。
我希望每个非抽象的IDrawable
都必须实现自己继承自ColorScheme
的类。 例如,抽象Window : IWindow
类没有这样的实现,但是PopupWindow : Window
类必须具有相应类型的PopupWindowColorScheme : ColorScheme
,其中PopupWindow
的作者将定义如何将类' Area
拆分为单独的区域。 每个PopupWindow
都有自己的这种类型的实例来包含它的特定颜色。
这可能吗? 如果没有,是否有另一种方法可以强制IDrawable
类型的作者指定将其区域分割为可着色区域的方法?
你不能强迫每个IDrawable
拥有的唯一实现ColorScheme
(例如多个不同的实现IDrawable
可以使用PopupWindowColorScheme
)。 但是,您可以使用泛型类型约束来添加实现接口的其他要求,如下所示:
public interface IDrawable<TColorScheme>
where TColorScheme : ColorScheme
{
Area ScreenArea { get; }
List<char[]> DisplayChars { get; }
//some other properties...
TColorScheme ColorScheme { get; }
}
现在, IDrawable
每个实现IDrawable
需要指定要使用的ColorScheme
类型。 但是,消费者可能只是实现IDrawable<ColorScheme>
,这种目的会失败(取决于您的要求)。 我们可以进一步:
public interface IDrawable<TColorScheme>
where TColorScheme : ColorScheme, new()
{
}
public abstract class ColorScheme { }
这里,由于ColorScheme
是抽象的,并且泛型类型约束需要提供的类型参数来实现无参数构造函数( new()
),因此ColorScheme
本身不能用作参数。 任何实现类都需要指定ColorScheme
的自定义实现,它提供一个公共的无参数构造函数。
但我们可以走得更远:
public interface IDrawable { }
public interface IDrawable<TDrawable, TColorScheme> : IDrawable
where TDrawable : IDrawable, new()
where TColorScheme : ColorScheme<TDrawable>, new()
{
object ScreenArea { get; }
List<char[]> DisplayChars { get; }
//some other properties...
TColorScheme ColorScheme { get; }
}
public abstract class ColorScheme<TDrawable>
where TDrawable : IDrawable, new()
{
}
在这里,每个实施IDrawable
有指定什么ColorScheme
它采用每 ColorScheme
也有指定什么IDrawable
它适用于。 并且因为每个都需要无参数构造函数,所以它们都不能指定公共基类型。 实现这一点现在看起来有点奇怪:
public class MyDrawable : IDrawable<MyDrawable, MyColorScheme> { }
public class MyColorScheme : ColorScheme<MyDrawable> { }
仍然可以实现可重用的ColorScheme
或IDrawable
(例如MyOtherDrawable : MyDrawable
使用MyColorScheme
)。 但是,在我看来,这开始变得相当繁琐和冗长。 在一般情况下,除非你有技术的原因,你必须使用一个类型约束,我会避免使用它,因为你会经常发现它在未来的限制太多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.