Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 静态方法无法实现接口方法,为什么?_C# - Fatal编程技术网

C# 静态方法无法实现接口方法,为什么?

C# 静态方法无法实现接口方法,为什么?,c#,C#,编译器错误:XXX.Foo()无法实现接口成员,因为它是静态的 为什么静态方法不能实现接口方法?接口定义了对象必须响应的行为。 因为Foo是一个静态方法,所以对象不响应它。换句话说,你不能写 interface IXXX { void Foo(); } class XXX : IXXX { public static void Foo() { Console.WriteLine("From XXX"); } } class Program

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


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

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

interface IXXX
{
    void Foo();
}

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


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

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

请参阅本线程,了解其背后的原因

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

先前关于SO的问题也涉及完全相同的问题:

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

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

因为接口成员是公共的且可重写的,并且静态方法在设计上不能被重写或抽象,接口在这里定义了一个可访问的契约,它必须通过具体的实现来实现(有尽可能多的抽象实现步骤和继承的接口),据我所知,没有办法创建一个抽象的静态方法。

好吧,我相信在泛型类型参数的情况下应该允许它。它可能简化了合同单例类。以下是一个例子:

XXX myXXX = new XXX();
myXXX.Foo();
公共接口的可扩展性{
//一些限制。。。
数据行ObjToRow(对象obj);
对象RowToObj(数据行dr);
}
//T将是从IEntity继承的具有默认构造函数签名的任何类。
公共接口IMyContract{
T read(),其中T:ententity;
void write(T对象),其中T:IEntity;
}
//班上的一切都是静态的
公共静态类SqlProvider:IMyContract{
公共静态T read(),其中T:IEntity{
DataRow dr=[从数据库读取]
返回T.RowToObj(dr);
}
//在这里编译错误。。。。
公共静态无效写入(T obj),其中T:Entity{
数据行dr=T.ObjToRow(obj);
[…将数据行灾难恢复提交到数据库…]
}
}
公共静态类MyAppleEntity:Entity{
[…正常执行电子商务合同…]
}
公共静态类MyOrangeEntity:Entity{
[…正常执行电子商务合同…]
}
公共类MyTest{
无效阅读(){
MyAppleEntity apple=SqlProvider.Read();
MyOrangeEntity orange=SqlProvider.Read();
SqlProvider.write(苹果);
SqlProvider.write(橙色);
} 
}
唯一一次类型引用隐式地出现在SqlProvider.read()和write()中,并且在调用点T是完全一致的。没有接口的静态实现,我不得不这样写

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

}
公共类MyAppleEntity:Entity{
[…正常执行电子商务合同…]
}
.....
public T read(),其中T:IEntity,new(){
DataRow dr=[从数据库读取]
返回新的T().RowToObj(dr);
}

几乎没有什么不同,但没有那么优雅

这没有道理。如何在XXX的派生类中实现接口?没有理由不能从实现中调用静态成员。@leppie,您可以有一个“type方法”;其中没有隐式
this
,但它确实在运行时从类型解析了方法。不过,很少会使用它们的情况可以通过实例方法或反射来满足,因此我并不迫切需要它们。@Jon Hanna:可以,但编译器会抱怨无法解析正确的方法。@leppie。用反射技术它不能,用实例方法它可以。是否需要足够的压力来要求更改语言?我会说不,虽然有时我自己也想要它。我相信这就是函数语言所说的“函子”。
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);
  }