为什么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;
    }

    ....

 }

当前回答

接口是已定义可用功能的抽象集合。

该接口中的方法是否表现为静态行为是应该隐藏在接口后面的实现细节。将接口方法定义为静态是错误的,因为您将不必要地强制该方法以某种方式实现。

如果方法被定义为静态的,那么实现接口的类就不会像它应该的那样被封装。在面向对象设计中,封装是一件值得努力的事情(我不会详细说明原因,你可以在这里阅读:http://en.wikipedia.org/wiki/Object-oriented)。因此,在接口中不允许使用静态方法。

其他回答

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

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”约束(因为知道一个类是否具有具有特定签名的构造函数似乎与知道它是否具有具有特定签名的静态方法在难度上相当)。

您想要的是允许通过Type或该类型的任何实例调用静态方法。这至少会导致歧义,这不是一个理想的特征。

关于这是否重要,这是最佳实践,以及这样做是否存在性能问题,将会有无休止的争论。通过简单地不支持它,c#使我们不必担心它。

遵循这一愿望的编译器也可能会失去一些优化,而这些优化可能会带来实例方法和静态方法之间更严格的分离。

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

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

大多数人似乎忘记了在OOP中,类也是对象,所以它们有消息,出于某种原因,c#将其称为“静态方法”。 实例对象和类对象之间存在差异的事实只显示了语言中的缺陷或缺点。 对c#持乐观态度…

I think the question is getting at the fact that C# needs another keyword, for precisely this sort of situation. You want a method whose return value depends only on the type on which it is called. You can't call it "static" if said type is unknown. But once the type becomes known, it will become static. "Unresolved static" is the idea -- it's not static yet, but once we know the receiving type, it will be. This is a perfectly good concept, which is why programmers keep asking for it. But it didn't quite fit into the way the designers thought about the language.

因为它不可用,所以我采用如下所示的方式使用非静态方法。虽然不太理想,但至少对我来说,我找不到比这更有意义的方法了。

public interface IZeroWrapper<TNumber> {
  TNumber Zero {get;}
}

public class DoubleWrapper: IZeroWrapper<double> {
  public double Zero { get { return 0; } }
}