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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/577749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 09:00:09  来源:igfitidea点击:

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

c#.netinterfacestatic-methods

提问by tpower

I am developing a set of classes that implement a common interface. A consumer of my library shall expect each of these classes to implement a certain set of static functions. Is there anyway that I can decorate these class so that the compiler will catch the case where one of the functions is not implemented.

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

I know it will eventually be caught when building the consuming code. And I also know how to get around this problem using a kind of factory class.

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

Just curious to know if there is any syntax/attributes out there for requiring static functions on a class.

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

EdRemoved the word 'interface' to avoid confusion.

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

采纳答案by Marc Gravell

No, there is no language support for this in C#. There are two workarounds that I can think of immediately:

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

  • use reflection at runtime; crossed fingers and hope...
  • use a singleton / default-instance / similar to implement an interface that declares the methods
  • 在运行时使用反射;交叉手指和希望......
  • 使用单例/默认实例/类似来实现声明方法的接口

(update)

更新

Actually, as long as you have unit-testing, the first option isn't actually as bad as you might think if (like me) you come from a strict "static typing" background. The fact is; it works fine in dynamic languages. And indeed, this is exactly how my generic operatorscode works - it hopesyou have the static operators. At runtime, if you don't, it will laugh at you in a suitably mocking tone... but it can't check at compile-time.

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

回答by mqp

Unfortunately, no, there's nothing like this built into the language.

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

回答by dsimcha

No, there would be no point in this feature. Interfaces are basically a scaled down form of multiple inheritance. They tell the compiler how to set up the virtual function table so that non-static virtual methods can be called properly in descendant classes. Static methods can't be virtual, hence, there's no point in using interfaces for them.

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

回答by Jon Skeet

No. Basically it sounds like you're after a sort of "static polymorphism". That doesn't exist in C#, although I've suggested a sort of "static interface" notion which could be useful in terms of generics.

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

One thing you coulddo is write a simple unit test to verify that all of the types in a particular assembly obey your rules. If other developers will also be implementing the interface, you could put that test code into some common place so that everyone implementing the interface can easily test their own assemblies.

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

回答by Jeff Yates

While there is no language support for this, you could use a static analysis tool to enforce it. For example, you could write a custom rule for FxCop that detects an attribute or interface implementation on a class and then checks for the existence of certain static methods.

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

回答by Trap

The approach that gets you closer to what you need is a singleton, as Marc Gravell suggested.

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

Interfaces, among other things, let you provide some level of abstraction to your classes so you can use a given API regardless of the type that implements it. However, since you DO need to know the type of a static class in order to use it, why would you want to enforce that class to implement a set of functions?

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

Maybe you could use a custom attribute like [ImplementsXXXInterface] and provide some run time checking to ensure that classes with this attribute actually implement the interface you need?

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

回答by MindModel

The singleton pattern does not help in all cases. My example is from an actual project of mine. It is not contrived.

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

I have a class (let's call it "Widget") that inherits from a class in a third-party ORM. If I instantiate a Widget object (therefore creating a row in the db) just to make sure my static methods are declared, I'm making a bigger mess than the one I'm trying to clean up.

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

If I create this extra object in the data store, I've got to hide it from users, calculations, etc.

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

I use interfaces in C# to make sure that I implement common features in a set of classes.

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

Some of the methods that implement these features require instance data to run. I code these methods as instance methods, and use a C# interface to make sure they exist in the class.

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

Some of these methods do not require instance data, so they are static methods. If I could declare interfaces with static methods, the compiler could check whether or not these methods exist in the class that says it implements the interface.

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

回答by Jeff Sharp

This is a great question and one that I've encountered in my projects.

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

Some people hold that interfaces and abstract classes exist for polymorphism only, not for forcing types to implement certain methods. Personally, I consider polymorphism a primary use case, and forced implementation a secondary. I do use the forced implementation technique fairly often. Typically, it appears in framework code implementing a template pattern. The base/template class encapsulates some complex idea, and subclasses provide numerous variations by implementing the abstract methods. One pragmatic benefit is that the abstract methods provide guidance to other developers implementing the subclasses. Visual Studio even has the ability to stub the methods out for you. This is especially helpful when a maintenance developer needs to add a new subclass months or years later.

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

The downside is that there is no specific support for some of these template scenarios in C#. Static methods are one. Another one is constructors; ideally, ISerializable should force the developer to implement the protected serialization constructor.

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

The easiest approach probably is (as suggested earlier) to use an automated test to check that the static method is implemented on the desired types. Another viable idea already mentioned is to implement a static analysis rule.

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

A third option is to use an Aspect-Oriented Programming framework such as PostSharp. PostSharp supports compile-time validation of aspects. You can write .NET code that reflects over the assembly at compile time, generating arbitrary warnings and errors. Usually, you do this to validate that an aspect usage is appropriate, but I don't see why you couldn't use it for validating template rules as well.

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

回答by Daniel

If you're just after getting those compiler errors, consider this setup:

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

  1. Define the methods in an interface.
  2. Declare the methods with abstract.
  3. Implement the public static methods, and have the abstract method overrides simply call the static methods.
  1. 在接口中定义方法。
  2. 用抽象声明方法。
  3. 实现公共静态方法,并让抽象方法覆盖简单地调用静态方法。

It's a little bit of extra code, but you'll know when someone isn't implementing a required method.

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