繁体   English   中英

是否可以将基类限制为特定的子类?

[英]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类之外在技术上也没有坏处,完全不需要非通用基类。 我只是选择了前一种方法,因为限制属性的使用比阻止某人对基类进行子类化更重要。

根据我们的评论,您可以使用EditorBrowsable属性从引用它的项目中隐藏该方法。 但是请注意,它只是将它隐藏在 IntelliSense 中,如果用户要输入ExampleMarkupExtensionBase ,则该类仍然存在并且可以使用。

[EditorBrowsable(EditorBrowsableState.Never)]
public abstract class ExampleMarkupExtensionBase : MarkupExtension

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM