关于c#:static方法无法实现接口方法,为什么?


static method cannot implement interface method, why?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
interface IXXX
{
    void Foo();
}

class XXX : IXXX
{
    public static void Foo()
    {
        Console.WriteLine("From XXX");
    }
}


class Program
{
    static void Main(string[] args)
    {
        XXX.Foo();

    }
}

编译器错误:xxx.foo()无法实现接口成员,因为它是静态的。

为什么静态方法不能实现接口方法?


请参阅JoelonSoftware中的这个线程,它描述了这背后的原因。

基本上,接口是使用者和提供者之间的契约,静态方法属于类,而不是类的每个实例。

之前的一个问题同样涉及到同样的问题:为什么不允许静态方法实现接口?


接口定义对象必须响应的行为。因为foo是一个静态方法,所以对象不响应它。换句话说,你不能写…

1
2
XXX myXXX = new XXX();
myXXX.Foo();

换句话说,myxxx不能完全满足接口的要求。


您可以使用接口来避免在实例化期间使用具体的类。不能通过实例化类访问静态方法,因此不允许使用静态方法实现接口方法。


如果我们将接口视为一个对象可以执行接口中列出的方法的承诺,那么静态实现的思想就成了问题。如果实现是静态的,则不能编写新的implementingObject().implementedMethod。对象无法执行该方法,类可以。


好吧,我认为在泛型类型参数的情况下应该允许这样做。它可能简化了契约单例类。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public interface IEntity {
   // some constrains...
  DataRow ObjToRow(object obj);
  object RowToObj(DataRow dr);
}

//T would be any class inherites from IEntity with default contructor signature.
public interface IMyContract {
  T read<T>() where T : IEntity;  
  void write<T>(T object) where T : IEntity;
}

//everything in the class is static
public static class SqlProvider : IMyContract {

  public static T read<T>() where T: IEntity {
    DataRow dr = [reading from database]
    return T.RowToObj(dr);
  }

  //compile error here....
  public static void write<T>(T obj) where T : IEntity {
    DataRow dr = T.ObjToRow(obj);

   [ ... commit data row dr to database ... ]

  }
}

public static class MyAppleEntity : IEntity  {
  [... implement IEntity contract normally ... ]
}

public static class MyOrangeEntity : IEntity {
   [... implement IEntity contract normally ... ]
}

public class MyTest {
  void reading() {
     MyAppleEntity apple = SqlProvider.Read<MyAppleEntity>();
     MyOrangeEntity orange = SqlProvider.Read<MyOrangeEntity>();

     SqlProvider.write<MyAppleEntity>(apple);
     SqlProvider.write<MyOrangeEntity>(orange);
  }

}

唯一一次类型引用隐式出现在sqlprovider.read()和write()中,而t在调用点是完全相同的。如果没有接口的静态实现,我就不得不这样写。

1
2
3
4
5
6
7
8
9
10
public class MyAppleEntity : IEntity  {
  [... implement IEntity contract normally ... ]
}

  .....

  public T read<T>() where T: IEntity, new() {
    DataRow dr = [reading from database]
    return new T().RowToObj(dr);
  }

有点不同,但不太优雅。


因为接口成员是公共的和可重写的,并且静态方法在设计上不能被重写或抽象,所以这里的接口定义了一个可访问的协定,该协定必须通过其具体实现来实现(在这两者之间有许多抽象实现和继承接口的步骤),据我所知,不存在任何WA。创建抽象静态方法。