2010-10-18 13 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(); 

    } 
} 

Error del compilador: XXX.Foo() no puede implementar un miembro de la interfaz porque es estático.método estático no puede implementar el método de interfaz, ¿por qué?

¿Por qué un método estático no puede implementar un método de interfaz?

+0

No tiene sentido. ¿Cómo implementarías la interfaz en una clase derivada de XXX? Sin embargo, no hay ninguna razón por la que no pueda llamar al miembro estático de la implementación. – leppie

+1

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

+0

@leppie, usted ** podría ** tener un "método de tipo"; donde no había un 'this' implícito, pero resolvió el método en tiempo de ejecución del tipo. Sin embargo, las raras ocasiones en que se usarían pueden ser atendidas por métodos de instancia o por reflexión, por lo que no es necesario presionar la OMI. –

Respuesta

11

Vea este hilo de JoelOnSoftware describiendo las razones detrás de esto.

Básicamente, la interfaz es el contrato entre el consumidor y el proveedor, y un método estático pertenece a la clase, y no a cada instancia de la clase como tal.

una pregunta anterior sobre el SO también tratar con exactamente la misma pregunta: Why Doesn't C# Allow Static Methods to Implement an Interface?

4

Una interfaz define el comportamiento al que un objeto debe responder. Como Foo es un método estático, el objeto no responde. En otras palabras, no podría escribir ...

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

En otras palabras, myXXX no satisface completamente los requisitos de la interfaz.

2

Si nos fijamos en las interfaces como una promesa de que un objeto puede realizar los métodos enumerados en la interfaz, entonces THS idea de aplicación estática se convierte problemático. Si la implementación es estática, no puede escribir el nuevo ImplementingObject(). ImplementedMthod. El objeto no puede realizar el método, la clase puede.

2

Utiliza la interfaz para evitar el uso de clases concretas durante la creación de instancias. No puede acceder al método estático a través de una clase instanciada, por lo que no está permitido implementar métodos de interfaz con métodos estáticos.

0

Como el miembro de la interfaz es público e invalidable, y ese método estático no puede ser anulado o abstracto, las interfaces están aquí para definir un contrato accesible que debe implementarse mediante su implementación concreta (con tantos pasos de implementaciones abstractas & heredado interfaces entre) y hasta donde yo sé, no hay forma de crear un método estático abstracto.

1

Bueno, creo que debería permitirse en el caso de un parámetro de tipo genérico. Probablemente simplificó la clase contractual de singleton. Aquí está un ejemplo:

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

} 

La única vez que una referencia de tipo implícita está en el SqlProvider.read() y write() y T es la identidad así en el punto de invocación. Sin la implementación estática de la interfaz, me veo obligado a escribir así.

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

Muy poco diferente, pero no del todo elegante.

+0

Creo que esto es lo que los lenguajes funcionales llaman 'functor'. –

Cuestiones relacionadas