[英]Is it possible to restrict a base class to a specific subclass?
我需要一个只对一个特定子类可用的基类。 这是由于您无法将Attribute
定义为泛型的内部类的限制。
我们想要在泛型中定义属性的原因是,当您这样做并将其类型设置为protected
,该属性现在仅可用于您的基类的子类,从而保持您的 API 干净。
例如,考虑从MarkupExtension
继承的抽象类ExampleMarkupExtension<T>
。 我想将属性StaticInfoAttribute
定义为内部类,因此它仅可用于ExampleMarkupExtension<T>
子类。
但是,如上所述,您不能将属性定义为泛型的内部类,因此我的解决方法是创建第二个非泛型ExampleMarkupExtensionBase
类,该类继承自MarkupExtension
,将StaticInfoAttribute
定义为内部类,然后使用泛型继承自该类。
现在的问题是我的层次结构中有一个额外的类,任何人都可以创建子类。 虽然从技术上讲它是无害的,但我喜欢保持 API 表面区域的清洁。
ExampleMarkupExtensionBase
: 非泛型抽象基类这是定义属性的类,该属性应该只对此类的子类可用。 这个类之所以存在是因为我不能将StaticInfoAttribute
放在StaticInfoAttribute
的通用抽象基类ExampleMarkupExtension<T>
中。
public abstract class ExampleMarkupExtensionBase : MarkupExtension {
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
protected class StaticInfoAttribute : Attribute {
public StaticInfoAttribute(string value) => Value = value;
public readonly string Value;
}
}
ExampleMarkupExtension<T>
:通用抽象基类该类包含对此类的子类而言唯一的静态成员。 它通过使用子类作为基类的类型参数来实现这一点(参见where
子句)。 静态字段的值是从属性设置的,因此它只对上述ExampleMarkupExtension
这个特定子类有任何用处。
public abstract class ExampleMarkupExtension<T> : ExampleMarkupExtensionBase
where T : ExampleMarkupExtension<T> {
static ExampleMarkupExtension() => Value = typeof(T).GetRequiredCustomAttribute<StaticInfoAttribute>().Value;
public static readonly string Value;
public sealed override object ProvideValue(IServiceProvider serviceProvider)
=> Value;
}
有些人可能会问,保持原样有什么危害。 从技术上讲,让一个人ExampleMarkupExtensionBase
并没有错。 没有任何意义。
就此而言,将StaticInfoAttribute
类之外在技术上也没有坏处,完全不需要非通用基类。 我只是选择了前一种方法,因为限制属性的使用比阻止某人对基类进行子类化更重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.