有没有办法强制C#类实现某些静态函数?

我正在开发一组实现通用接口的类。 我的库的使用者应该期望这些类中的每一个都实现一组静态函数。 无论如何,我可以装饰这些类,以便编译器将捕获其中一个函数未实现的情况。

我知道在构建消费代码时最终会被捕获。 我也知道如何使用一种工厂类解决这个问题。

只是想知道是否有任何语法/属性要求类上的静态函数。

Ed删除了“界面”这个词以避免混淆。

不,C#中没有语言支持。 我可以立即想到两种解决方法:

  • 在运行时使用reflection; 交叉的手指和希望……
  • 使用singleton / default-instance / similar来实现声明方法的接口

更新

实际上,只要你有unit testing,第一个选项实际上并不像你想象的那样(如我)你来自严格的“静态类型”背景。 事实上; 它在动态语言中运行良好。 事实上,这正是我的通用运算符代码的工作原理 – 它希望你有静态运算符。 在运行时,如果你不这样做,它会以适当的嘲弄语气嘲笑你……但它无法在编译时检查。

没有。基本上听起来你是在追求一种“静态多态”。 这在C#中不存在,尽管我已经提出了一种“静态接口”概念,它在generics方面很有用 。

可以做的一件事是编写一个简单的unit testing来validation特定程序集中的所有类型是否符合您的规则。 如果其他开发人员也将实现该接口,您可以将该测试代码放入一些常见位置,以便实现该接口的每个人都可以轻松地测试他们自己的程序集。

这是一个很好的问题,也是我在项目中遇到的问题。

有些人认为接口和抽象类只存在于多态,而不是强制类型实现某些方法。 就个人而言,我认为多态性是主要用例,并强制实现次要。 我经常使用强制实现技术。 通常,它出现在实现模板模式的框架代码中。 基类/模板类封装了一些复杂的想法,子类通过实现抽象方法提供了许多变体。 一个实用的好处是抽象方法为实现子类的其他开发人员提供了指导。 Visual Studio甚至可以为您存储方法。 当维护开发人员需要在几个月或几年后添加新的子类时,这尤其有用。

缺点是C#中的某些模板方案没有特定的支持。 静态方法是一种。 另一个是构造函数; 理想情况下,ISerializable应该强制开发人员实现受保护的序列化构造函数。

最简单的方法可能是(如前所述)使用自动化测试来检查静态方法是否在所需类型上实现。 已经提到的另一个可行的想法是实现静态分析规则。

第三种选择是使用面向方面的编程框架,如PostSharp 。 PostSharp支持方面的编译时validation。 您可以编写在编译时反映程序集的.NET代码,生成任意警告和错误。 通常,您这样做是为了validation方面使用是否合适,但我不明白为什么您也不能使用它来validation模板规则。

不幸的是,不,这种语言中没有这种内容。

虽然没有语言支持,但您可以使用静态分析工具来强制执行它。 例如,您可以为FxCop编写一个自定义规则,用于检测类上的属性或接口实现,然后检查某些静态方法是否存在。

单身模式在所有情况下都没有帮助。 我的例子来自我的实际项目。 这不是人为的。

我有一个inheritance自第三方ORM中的类的类(我们称之为“Widget”)。 如果我实例化一个Widget对象(因此在db中创建一行)只是为了确保我的静态方法被声明,我正在制造一个比我正在尝试清理的更糟糕的东西。

如果我在数据存储中创建这个额外的对象,我必须将其隐藏在用户,计算等之外。

我在C#中使用接口以确保我在一组类中实现通用function。

实现这些function的一些方法需要运行实例数据。 我将这些方法编码为实例方法,并使用C#接口确保它们存在于类中。

其中一些方法不需要实例数据,因此它们是静态方法。 如果我可以使用静态方法声明接口,则编译器可以检查这些方法是否存在于表示它实现接口的类中。

不,这个function没有意义。 接口基本上是多重inheritance的缩小forms。 它们告诉编译器如何设置虚函数表,以便可以在后代类中正确调用非静态虚方法。 静态方法不能是虚拟的,因此,为它们使用接口没有意义。

正如Marc Gravell建议的那样,让你更接近你需要的方法是单身人士。

除了其他方面,接口允许您为类提供某种级别的抽象,因此您可以使用给定的API,而不管实现它的类型如何。 但是,由于您需要知道静态类的类型才能使用它,为什么要强制该类来实现一组函数?

也许您可以使用[ImplementsXXXInterface]之类的自定义属性并提供一些运行时检查以确保具有此属性的类实际实现您需要的接口?

如果您刚刚收到这些编译器错误,请考虑以下设置:

  1. 在接口中定义方法。
  2. 用abstract声明方法。
  3. 实现公共静态方法,并使用抽象方法覆盖只需调用静态方法。

这是一些额外的代码,但你会知道什么时候有人没有实现所需的方法。