Как я могу реализовать статические методы на интерфейсе?


У меня есть сторонняя C++ DLL, которую я вызываю из C#.

методы являются статическими.

Я хочу абстрагировать его, чтобы сделать некоторые модульные тесты, поэтому я создал интерфейс со статическими методами в нем, но теперь мои ошибки программы с:

модификатор 'static' недопустим для данного элемента

MyMethod cannot be accessed with an instance reference; qualify it with a type name instead

Как я могу достичь этой абстракции?

мой код выглядит так

private IInterfaceWithStaticMethods MyInterface;

public MyClass(IInterfaceWithStaticMethods myInterface)
{
  this.MyInterface = myInterface;
}

public void MyMethod()
{
  MyInterface.StaticMethod();
}
5 52

5 ответов:

вы не можете определить статические элементы интерфейса в C#. Интерфейс-это контракт экземпляров.

Я бы рекомендовал создать интерфейс, как вы сейчас, но без ключевого слова static. Затем создайте класс StaticIInterface который реализует интерфейс и вызывает статические методы C++. Чтобы выполнить модульное тестирование, создайте другой класс FakeIInterface, что также реализует интерфейс, но делает то, что вам нужно для обработки ваших модульных тестов.

как только вы имеете эти 2 класса определены, вы можете создать тот, который вам нужен для вашей среды, и передать его в MyClass'конструктор С.

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

что вы можете сделать, это использовать явную реализацию интерфейса:

public interface IMyInterface
{
    void MyMethod();
}

public class MyClass : IMyInterface
{
    static void MyMethod()
    {
    }

    void IMyInterface.MyMethod()
    {
        MyClass.MyMethod();
    }
}

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

статические члены совершенно законны в среде CLR, только не C#.

вы можете реализовать некоторый клей в IL, чтобы связать детали реализации.

Не уверен, что компилятор C# позволит их вызывать?

см.: 8.9.4 определение типа интерфейса ECMA-335.

типы интерфейса обязательно являются неполными, так как они ничего не говорят о представлении значений типа интерфейса. Для этого причина, интерфейс определение типа не должно содержать поля определения значений типа интерфейса (т. е. полей экземпляра), хотя он может объявлять статические поля (см. §8.4.3).

аналогично, определение типа интерфейса не предоставляют реализации для любых методов по значениям его типа. Однако определение типа интерфейса может-и обычно определяет-контракты методов (имя метода и подпись метода), которые должны быть реализованы с помощью поддерживающие типы. Тип интерфейса определение может определять и реализуйте статические методы (см. §8.4.3), поскольку статические методы связано с самим типом интерфейса, а не с каким-либо значением типа.

вы можете вызвать его с отражением:

MyInterface.GetType().InvokeMember("StaticMethod", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null);

, почему вы не можете иметь статический метод в интерфейсе: почему C# не позволяет статическим методам реализовать интерфейс?

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

ie

public static class MyStaticClass
{
    public static void MyStaticMethod()
    {...}
}

public interface IStaticWrapper
{
    void MyMethod();
}

public class MyClass : IStaticWrapper
{
    public void MyMethod()
    {
        MyStaticClass.MyStaticMethod();
    }
}