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

    ....

 }

当前回答

举一个例子,我既没有接口方法的静态实现,也没有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,实例化一个实例的开销是最小的。但是,在这种情况下它会很好。

其他回答

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

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

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

这里的大多数答案似乎都没有抓住重点。多态性不仅可以在实例之间使用,还可以在类型之间使用。当我们使用泛型时,这是经常需要的。

假设我们在泛型方法中有类型参数,我们需要对它做一些操作。我们不想实例化,因为我们不知道构造函数。

例如:

Repository GetRepository<T>()
{
  //need to call T.IsQueryable, but can't!!!
  //need to call T.RowCount
  //need to call T.DoSomeStaticMath(int param)
}

...
var r = GetRepository<Customer>()

不幸的是,我只能想出一些“丑陋”的选择:

Use reflection Ugly and beats the idea of interfaces and polymorphism. Create completely separate factory class This might greatly increase the complexity of the code. For example, if we are trying to model domain objects, each object would need another repository class. Instantiate and then call the desired interface method This can be hard to implement even if we control the source for the classes, used as generic parameters. The reason is that, for example we might need the instances to be only in well-known, "connected to DB" state.

例子:

public class Customer 
{
  //create new customer
  public Customer(Transaction t) { ... }

  //open existing customer
  public Customer(Transaction t, int id) { ... }

  void SomeOtherMethod() 
  { 
    //do work...
  }
}

为了使用实例化来解决静态接口问题,我们需要做以下事情:

public class Customer: IDoSomeStaticMath
{
  //create new customer
  public Customer(Transaction t) { ... }

  //open existing customer
  public Customer(Transaction t, int id) { ... }

  //dummy instance
  public Customer() { IsDummy = true; }

  int DoSomeStaticMath(int a) { }

  void SomeOtherMethod() 
  { 
    if(!IsDummy) 
    {
      //do work...
    }
  }
}

这显然是丑陋的,也是不必要的,会使所有其他方法的代码复杂化。显然,这也不是一个优雅的解决方案!

假设你在问为什么你不能这样做:

public interface IFoo {
    void Bar();
}

public class Foo: IFoo {
    public static void Bar() {}
}

This doesn't make sense to me, semantically. Methods specified on an interface should be there to specify the contract for interacting with an object. Static methods do not allow you to interact with an object - if you find yourself in the position where your implementation could be made static, you may need to ask yourself if that method really belongs in the interface. To implement your example, I would give Animal a const property, which would still allow it to be accessed from a static context, and return that value in the implementation.

public class Animal: IListItem {
    /* Can be tough to come up with a different, yet meaningful name!
     * A different casing convention, like Java has, would help here.
     */
    public const string AnimalScreenName = "Animal";
    public string ScreenName(){ return AnimalScreenName; }
}

对于更复杂的情况,您总是可以声明另一个静态方法并委托给它。在尝试给出一个例子的过程中,我想不出您在静态和实例上下文中都要做一些非平凡的事情的任何理由,因此我将给您一个FooBar blob,并将其作为它可能不是一个好主意的指示。

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

你怎么称呼它??


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