繁体   English   中英

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

[英]Is there a way to force a C# class to implement certain static functions?

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

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

只是想知道是否有任何语法/属性需要在类上使用静态函数。

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

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

  • 在运行时使用反射; 交叉手指和希望......
  • 使用单例/默认实例/类似来实现声明方法的接口

更新

实际上,只要您进行单元测试,如果(像我一样)您来自严格的“静态类型”背景,那么第一个选项实际上并不像您想象的那么糟糕。 事实上; 它在动态语言中运行良好。 事实上,这正是我的通用运算符代码的工作方式 - 它希望您拥有静态运算符。 在运行时,如果您不这样做,它会以适当的嘲讽语气嘲笑您……但它无法在编译时检查。

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

可以做的一件事是编写一个简单的单元测试来验证特定程序集中的所有类型是否都遵守您的规则。 如果其他开发人员也将实现该接口,您可以将该测试代码放在某个公共位置,以便每个实现该接口的人都可以轻松地测试他们自己的程序集。

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

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

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

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

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

不幸的是,不,语言中没有类似的东西。

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

单例模式并非在所有情况下都有帮助。 我的例子来自我的一个实际项目。 它不是人为的。

我有一个从第三方 ORM 中的类继承的类(我们称之为“小部件”)。 如果我实例化一个 Widget 对象(因此在 db 中创建一行)只是为了确保我的静态方法被声明,我正在制造比我试图清理的更大的混乱。

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

我在 C# 中使用接口来确保我在一组类中实现公共功能。

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

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

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

正如 Marc Gravell 建议的那样,让您更接近所需的方法是单例。

接口,除其他外,让您为您的类提供某种级别的抽象,以便您可以使用给定的 API,而不管实现它的类型。 但是,既然您确实需要知道静态类的类型才能使用它,那么您为什么要强制该类实现一组函数呢?

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

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

  1. 在接口中定义方法。
  2. 用抽象声明方法。
  3. 实现公共静态方法,并让抽象方法覆盖简单地调用静态方法。

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

暂无
暂无

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

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