2010-10-18 17 views
9
interface IXXX 
{ 
    void Foo(); 
} 

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


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

    } 
} 

Errore del compilatore: XXX.Foo() non può implementare un membro dell'interfaccia perché è statico.non può implementare il metodo di interfaccia, perché?

Perché un metodo statico non può implementare un metodo di interfaccia?

+0

Non ha senso. Come implementeresti l'interfaccia in una classe derivata di XXX? Non c'è motivo per cui non puoi chiamare il membro statico dall'implementazione comunque. – leppie

+1

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

+0

@leppie, si ** potrebbe ** avere un "metodo tipo"; dove non c'era un implicito 'questo 'ma risolveva il metodo in fase di esecuzione dal tipo. Le rare occasioni in cui le usiamo possono essere soddisfatte con metodi di istanza o riflessione, quindi non c'è bisogno urgente di IMO. –

risposta

11

Vedere questo thread da JoelOnSoftware che descrive le ragioni alla base di questo.

Fondamentalmente l'interfaccia è il contratto tra il consumatore e il provider e un metodo statico appartiene alla classe e non ogni istanza della classe in quanto tale.

una precedente interrogazione su SO che fare anche con la stessa identica domanda: Why Doesn't C# Allow Static Methods to Implement an Interface?

4

Un'interfaccia definisce il comportamento a cui un oggetto deve rispondere. As Foo è un metodo statico, l'oggetto non risponde ad esso. In altre parole, non si poteva scrivere ...

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

In altre parole, myXXX non soddisfa pienamente i requisiti dell'interfaccia.

2

se guardiamo a interfacce come una promessa che un oggetto può eseguire i metodi elencati nell'interfaccia, poi THS idea di implementazione statica diventa problematico. Se l'implementazione è statica, non è possibile scrivere nuovo ImplementingObject(). ImplementedMthod. L'oggetto non può eseguire il metodo, la classe può.

2

Si utilizza l'interfaccia per evitare l'uso della classe di calcestruzzo durante l'istanziazione. Non è possibile accedere al metodo statico attraverso la classe istanziata, quindi l'implementazione dei metodi di interfaccia con metodi statici non è consentita.

0

Perché membro di interfaccia sono pubbliche e override, e che il metodo statico non può in base alla progettazione essere overrided o astratta, interfacce sono qui per definire un contratto di accesso che deve essere implementata dalla loro attuazione concreta (con altrettanti passaggi di implementazioni astratte & ereditarie interfacce tra) e per quanto ne so non c'è modo di creare un metodo statico astratto.

1

Beh, credo che dovrebbe essere consentito in caso di parametro di tipo generico. Probabilmente ha semplificato la classe contrattuale singleton. Ecco un esempio:

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

} 

L'unica volta un riferimento tipo è implicitamente nel SqlProvider.read() e scrivere() e T è un'identità ben al punto di invoke. Senza l'implementazione statica dell'interfaccia sono costretto a scrivere in questo modo.

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

Molto poco diverso ma non altrettanto elegante.

+0

Credo che questo sia ciò che i linguaggi funzionali chiamano un "functor". –

Problemi correlati