C#:在所有派生类中具有*必需*实现的静态基类方法存根[重复]

Posted

技术标签:

【中文标题】C#:在所有派生类中具有*必需*实现的静态基类方法存根[重复]【英文标题】:C#: static base-class method stub with a *required* implementation in all derived classes [duplicate] 【发布时间】:2013-03-14 16:10:29 【问题描述】:

我需要 C# 中静态抽象方法的替代方法:

// fantasy code
abstract public class BaseClass

    static abstract public void RequiredStaticMethod();

RequiredStaticMethod 我只有两个条件:

    所有派生类都必须实现它(由编译器强制执行)。 它必须在没有类实例的情况下可用;即,DerivedClass.RequiredStaticMethod() 必须有效。

实现这一目标的最佳方法是什么?

【问题讨论】:

你不能使用Interface吗? 这在 C# 中不受支持。已经讨论过here 和here 这个问题类似于***.com/questions/763344/… 这个提议的解决方案解决的实际业务需求是什么? @JonSkeet - 我希望使用反射:我有一个数据库中派生类名称的列表。这不可能吗? 【参考方案1】:

您无法在编译时验证它。但是,如果您要使用反射调用该方法(因此您不需要任何类型的多态性),您只需 document 说明每个具体派生类都必须实现特定方法,然后编写一个为所有派生类型搜索程序集并检查它们是否符合的单元测试。

它不如编译时检查好,但假设您可以控制所有涉及的程序集,并且假设您已经足够频繁地运行单元测试,它应该相当轻松。

【讨论】:

谢谢乔恩:这值得知道。【参考方案2】:

您不能在 C# 中执行此操作。相反,它可能会帮助您使用抽象实例方法和单例模式:

abstract public class BaseClass

    abstract public void RequiredStaticMethod();


sealed class Subclass : BaseClass

    public static readonly Subclass Instance = new Subclass();

    public void RequiredStaticMethod()     

您可能希望进一步描述您要解决的潜在问题。通常,您使用抽象类来解耦消费者与实际实现,方法是让他们使用抽象类型。然而,这显然不能用静态成员来完成。正如 Jon 评论的那样,我看不出你打算如何消费 BaseClass

您也可以使用接口,并通过反射找到所有实现类型。这将产生IFoo 的类型化迭代并以实例绑定方式调用您的方法:

class Program

    public static void Main()
    
        var classes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.GetInterface("IFoo") != null);
        foreach(var foo in classes.Select(c => Activator.CreateInstance(c)).Cast<IFoo>())
        
            foo.RequiredNonStaticMethod();
        
    


public interface IFoo

    void RequiredNonStaticMethod();


public class FooImpl : IFoo

    public void RequiredNonStaticMethod()
    
        Console.WriteLine("Foo");
    

【讨论】:

谢谢:我打算使用反射来调用派生类上的静态成员。我真的想要一种方法来确保他们一直在那里。因此我原来的问题中的编译时检查条件。不过,我可以看出我需要换一种方式来考虑这个问题。 这只是将“每个具体类都应该公开一个静态方法”的问题放到“每个具体类应该公开一个带有相关实例的静态字段或属性”的问题上——同时增加了它甚至是合理的限制因为它是一个单身人士。鉴于仍然存在编译器无法验证的条件,并且仍然需要通过反射查找内容,我宁愿不需要单例部分,并返回“未编译时检查”的方法" 位。 @JonSkeet 你说得对,我也喜欢你的反射+单元测试——而且我对我的提议也不完全满意。我仍然想知道 Ed 的问题是否也可以在不强制单个实例的情况下通过使用静态方法或单例来解决,而是通过使用 C# 的编译时特性来解决。例如,我的第二种选择不使用单例。但是,它需要无参数的构造函数,这也不理想。

以上是关于C#:在所有派生类中具有*必需*实现的静态基类方法存根[重复]的主要内容,如果未能解决你的问题,请参考以下文章

C# 中基类,虚类,抽象类,密封类,接口的区别

C#基础语法

C++ - 在派生类中静态初始化基类受保护的成员变量

使用基类中的函数静态调用纯虚函数的派生类实现

C#关键字学习

C# virtual 和 abstract 区别