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

    } 
} 

Ошибка компилятора: XXX.Foo() не может реализовать элемент интерфейса, поскольку он является статическим.Статический метод не может реализовать интерфейс, почему?

Почему статический метод не реализует метод интерфейса?

+0

Это не имеет смысла. Как реализовать интерфейс в производном классе XXX? Однако нет причин, по которым вы не можете называть статический член из реализации. – leppie

+1

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

+0

@leppie, вы ** можете ** иметь «метод типа»; где не было неявного 'this', но он разрешил метод во время выполнения из этого типа. Редкие случаи, которые могли бы их использовать, могут быть удовлетворены либо методами экземпляра, либо отражением, хотя это не настоятельная потребность ИМО. –

ответ

11

Посмотрите эту тему от JoelOnSoftware, описывая причины этого.

В основном интерфейс является договором между потребителем и поставщиком, а статический метод принадлежит классу, а не каждому экземпляру класса как такового.

Ранее вопрос о SO также иметь дело с точно таким же вопросом: Why Doesn't C# Allow Static Methods to Implement an Interface?

4

Интерфейс определяет поведение, на которое объект должен отвечать. Поскольку Foo - статический метод, объект не отвечает на него. Другими словами, вы не могли бы написать ...

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

Другими словами, myXXX не полностью удовлетворяет требованиям интерфейса.

2

Если мы посмотрим на интерфейсах как обещание, что объект может выполнять методы, перечисленные в интерфейсе, то тыс идеи статической реализации становится проблематичным. Если задание является статичным, то вы не можете написать новый ImplementingObject(). ImplementedMthod. Объект не может выполнить метод, класс может.

2

Вы используете интерфейс, чтобы избежать использования конкретного класса во время создания экземпляра. Вы не можете получить доступ к статическому методу через экземпляр класса, поэтому внедрение методов интерфейса со статическими методами не допускается.

0

Поскольку член интерфейса является общедоступным и переопределяемым, и этот статический метод не может быть переопределен или абстрактным по дизайну, интерфейсы здесь предназначены для определения доступного контракта, который должен быть реализован по их конкретной реализации (с таким количеством шагов абстрактных реализаций & унаследовано интерфейсы между ними), и насколько я знаю, нет способа создать абстрактный статический метод.

1

Ну, я считаю, что это допустимо в случае типового параметра типа. Это, вероятно, упростило контрактный одноэлементный класс. Ниже приведен пример:

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() и писать() и Т хорошо идентичность в точке Invoke. Без статической реализации интерфейса я вынужден писать вот так.

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

Очень маленький, но не совсем такой элегантный.

+0

Я считаю, что это то, что функциональные языки называют «функтором». –

Смежные вопросы