2010-10-18 6 views
9

Compiler-Fehler: XXX.Foo() kann kein Interface-Member implementieren, da es statisch ist.statische Methode kann Interface-Methode nicht implementieren, warum?

Warum kann eine statische Methode keine Schnittstellenmethode implementieren?

+0

Es ergibt keinen Sinn. Wie würden Sie die Schnittstelle in einer abgeleiteten Klasse von XXX implementieren? Es gibt keinen Grund, warum Sie das statische Element nicht von der Implementierung aus aufrufen können. – leppie

+1

http://stackoverflow.com/questions/259026/why-doesnt-callow-static-methods-to-implement-an-interface – bernhof

+0

@leppie, du ** könnte ** eine "type method" haben; wo es kein implizites "this" gab, aber es löste die Methode zur Laufzeit vom Typ. Die seltenen Gelegenheiten, die sie verwenden würden, können durch beide Instanzmethoden oder Reflexion, also nicht eine dringende Notwendigkeit IMO gesorgt werden. –

Antwort

11

Sehen Sie diesen Thread von JoelOnSoftware beschreibt die Gründe dafür.

Grundsätzlich ist die Schnittstelle der Vertrag zwischen dem Verbraucher und dem Anbieter, und eine statische Methode gehört zu der Klasse und nicht jede Instanz der Klasse als solche.

Eine frühere Frage auf SO auch mit der exakt gleichen Frage beschäftigen: Why Doesn't C# Allow Static Methods to Implement an Interface?

4

Eine Schnittstelle definiert das Verhalten, auf das ein Objekt reagieren muss. Da Foo eine statische Methode ist, reagiert das Objekt nicht darauf. Mit anderen Worten, Sie könnten nicht schreiben ...

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

Mit anderen Worten, myXXX nicht in vollem Umfang die Anforderungen der Schnittstelle genügen.

2

Wenn wir Schnittstellen als Versprechen sehen, dass ein Objekt die Methoden in der Schnittstelle aufgeführt durchführen kann, dann ths Idee der statischen Umsetzung wird problematisch. Wenn die Implementierung statisch ist, können Sie kein neues ImplementingObject() .ImplementedMthod schreiben. Das Objekt kann die Methode nicht ausführen, das kann die Klasse.

2

Sie verwenden die Schnittstelle, um die Verwendung konkreter Klassen während der Instanziierung zu vermeiden. Sie können nicht auf die statische Methode über die instanziierte Klasse zugreifen, daher ist das Implementieren von Schnittstellenmethoden mit statischen Methoden nicht zulässig.

0

Da Schnittstellenelemente öffentlich und übersteuerbar sind und diese statische Methode nicht übergangen oder abstrakt sein kann, definieren Schnittstellen hier einen barrierefreien Vertrag, der durch ihre konkrete Implementierung implementiert werden muss (mit so vielen Schritten abstrakter Implementierungen wie &) Schnittstellen zwischen) und soweit ich weiß gibt es keine Möglichkeit, eine abstrakte statische Methode zu erstellen.

1

Nun, ich glaube, es sollte im Falle von generischen Typ Parameter erlaubt. Es hat wahrscheinlich die vertragliche Singleton-Klasse vereinfacht. Hier ein Beispiel:

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

} 

Das einzige Mal, eine Art Referenz implizit in der SqlProvider.read ist() und write() und T ist gut Identität am Punkt von invoke. Ohne statische Implementierung der Schnittstelle bin ich gezwungen, so zu schreiben.

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

Sehr wenig anders, aber nicht ganz so elegant.

+0

Ich glaube, das ist das, was funktionale Sprachen nennen ‚Funktor‘. –

Verwandte Themen