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

    ....

 }

当前回答

我认为简单的答案是“因为它毫无用处”。 要调用接口方法,需要该类型的实例。从实例方法中,您可以调用任何您想要的静态方法。

其他回答

因为接口的目的是允许多态性,能够传递任意数量的已定义类的实例,这些类都已定义,以实现已定义的接口……确保在多态调用中,代码能够找到您正在调用的方法。允许静态方法实现接口是没有意义的,

你怎么称呼它??


public interface MyInterface { void MyMethod(); }
public class MyClass: MyInterface
{
    public static void MyMethod() { //Do Something; }
}

 // inside of some other class ...  
 // How would you call the method on the interface ???
    MyClass.MyMethod();  // this calls the method normally 
                         // not through the interface...

    // This next fails you can't cast a classname to a different type... 
    // Only instances can be Cast to a different type...
    MyInterface myItf = MyClass as MyInterface;  

当类实现接口时,它是在为接口成员创建实例。虽然静态类型没有实例,但在接口中使用静态签名是没有意义的。

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; } }
}

我的(简化的)技术原因是静态方法不在虚表中,调用站点是在编译时选择的。这和你不能有覆盖或虚拟静态成员的原因是一样的。要了解更多细节,你需要一个计算机专业毕业生或编译专家——而我两者都不是。

出于政治原因,我将引用Eric Lippert(他是一名编译器专家,拥有滑铁卢大学的数学、计算机科学和应用数学学士学位)的话:

...静态方法的核心设计原则,给它们命名的原则是…在编译时,总是可以准确地确定将调用什么方法。也就是说,可以仅通过对代码的静态分析来解析该方法。

请注意,Lippert确实为所谓的类型方法留出了空间:

也就是说,与类型相关联的方法(如静态方法),它不接受不可空的“this”参数(与实例或虚拟方法不同),而是调用的方法依赖于T的构造类型(与静态方法不同,它必须在编译时确定)。

但还没有被它的实用性所说服。

举一个例子,我既没有接口方法的静态实现,也没有Mark Brackett介绍的“所谓的类型方法”:

当从数据库存储中读取数据时,我们有一个通用的DataTable类来处理从任何结构的表中读取数据。所有特定于表的信息都放在每个表的一个类中,每个表还保存来自DB的一行的数据,并且必须实现IDataRow接口。IDataRow中包含了要从数据库中读取的表的结构描述。DataTable在从DB中读取数据之前必须向IDataRow请求数据结构。目前看起来是这样的:

interface IDataRow {
  string GetDataSTructre();  // How to read data from the DB
  void Read(IDBDataRow);     // How to populate this datarow from DB data
}

public class DataTable<T> : List<T> where T : IDataRow {

  public string GetDataStructure()
    // Desired: Static or Type method:
    // return (T.GetDataStructure());
    // Required: Instantiate a new class:
    return (new T().GetDataStructure());
  }

}

每个表只需要读取一次GetDataStructure,实例化一个实例的开销是最小的。但是,在这种情况下它会很好。