Подтвердить что ты не робот

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

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

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

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

Модификатор '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();
}
4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

public interface IMyInterface
{
    void MyMethod();
}

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

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

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

Ответ 3

Статические члены совершенно легальны в CLR, а не С#.

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

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

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

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

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

Ответ 4

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

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

Ответ 5

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

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

т

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

public interface IStaticWrapper
{
    void MyMethod();
}

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