为什么c#是这样设计的?

根据我的理解,一个接口只描述行为,并且服务于描述实现接口的类的契约义务。

如果类希望在共享方法中实现这种行为,为什么不应该呢?

以下是我想到的一个例子:

// These items will be displayed in a list on the screen.
public interface IListItem {
  string ScreenName();
  ...
}

public class Animal: IListItem {
    // All animals will be called "Animal".
    public static string ScreenName() {
        return "Animal";
    }
....
}

public class Person: IListItem {

    private string name;

    // All persons will be called by their individual names.
    public string ScreenName() {
        return name;
    }

    ....

 }

当前回答

在接口代表“契约”的程度上,静态类实现接口似乎是非常合理的。

上述论点似乎都忽略了合同的这一点。

其他回答

我猜这是短视。

在最初设计时,接口仅用于类的实例

IMyInterface val = GetObjectImplementingIMyInterface();
val.SomeThingDefinedinInterface();

只有引入接口作为泛型的约束,向接口中添加静态方法才有实际用途。

(回复评论:)我认为现在更改它需要更改CLR,这将导致与现有程序集不兼容。

因为接口是继承结构,静态方法继承不好。

供您参考:您可以通过为接口创建扩展方法来获得与您想要的类似的行为。扩展方法将是一个共享的、不可覆盖的静态行为。然而,不幸的是,这个静态方法不是契约的一部分。

c#和CLR应该像Java一样支持接口中的静态方法。静态修饰符是契约定义的一部分,确实有意义,具体来说,行为和返回值不会基于实例而变化,尽管在不同调用之间仍然可能不同。

也就是说,当您想在接口中使用静态方法而又不能使用时,我建议您使用注释。您将得到您正在寻找的功能。

我知道这是个老问题,但很有趣。这个例子并不是最好的。我认为如果你展示一个用例会更清楚:

string DoSomething<T>() where T:ISomeFunction
{
  if (T.someFunction())
    ...
}

仅仅使用静态方法实现接口并不能达到你想要的效果;所需要的是将静态成员作为接口的一部分。我当然可以想象出许多用例,特别是当它能够创建东西的时候。我可以提供两种可能有用的方法:

Create a static generic class whose type parameter will be the type you'd be passing to DoSomething above. Each variation of this class will have one or more static members holding stuff related to that type. This information could supplied either by having each class of interest call a "register information" routine, or by using Reflection to get the information when the class variation's static constructor is run. I believe the latter approach is used by things like Comparer<T>.Default(). For each class T of interest, define a class or struct which implements IGetWhateverClassInfo<T> and satisfies a "new" constraint. The class won't actually contain any fields, but will have a static property which returns a static field with the type information. Pass the type of that class or struct to the generic routine in question, which will be able to create an instance and use it to get information about the other class. If you use a class for this purpose, you should probably define a static generic class as indicated above, to avoid having to construct a new descriptor-object instance each time. If you use a struct, instantiation cost should be nil, but every different struct type would require a different expansion of the DoSomething routine.

这些方法都不太吸引人。另一方面,我希望如果CLR中存在能够干净地提供这类功能的机制,.net将允许指定参数化的“new”约束(因为知道一个类是否具有具有特定签名的构造函数似乎与知道它是否具有具有特定签名的静态方法在难度上相当)。