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

Не использовать явно не реализованный интерфейс?

Скажем, вы определяете какой-то произвольный интерфейс:

public interface IInterface
{
    void SomeMethod();
}

И пусть говорят, что есть некоторые классы, которые имеют соответствующий открытый интерфейс, даже если они не реализуют IInterface. IE:

public class SomeClass
{
    public void SomeMethod()
    {
       // some code
    }
}

есть ли способ получить ссылку IInterface на экземпляр SomeClass? IE:

SomeClass myInstance = new SomeClass();
IInterface myInterfaceReference = (IInterface)myInstance;

Спасибо

4b9b3361

Ответ 1

Нет никакого способа сделать это. Если тип не реализует интерфейс, тогда нет возможности применить его. Лучшим способом достижения поведения, аналогичного тому, который вы хотите, является создание типа оболочки, который обеспечивает реализацию IInterface для SomeClass.

public static class Extensions {
  private sealed class SomeClassWrapper : IInterface {
    private readonly SomeClass _someClass;

    internal SomeClassWrapper(SomeClass someClass) {
      _someClass = someClass;
    }

    public void SomeMethod() {
      _someClass.SomeMethod();
    }
  }

  public static IInterface AsIInterface(this SomeClass someClass) {
    return new SomeClassWrapper(someClass);
  }
}

Затем вы можете сделать следующий вызов

SomeClass myInstance = new SomeClass();
IInterface myInterface = myInstance.AsIInterface();

Ответ 2

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

public class InterfaceWrapper : IInterface
{
    private readonly SomeClass _someClass;

    public InterfaceWrapper(SomeClass someClass) { _someClass = someClass; }

    public void SomeMethod() { _someClass.SomeMethod(); }
}

Ответ 3

Нет. Просто потому, что у двух классов есть методы с одним и тем же именем, это не значит, что они соблюдают один и тот же контракт. Именно поэтому вы определяете контракт, явно реализуя соответствующие интерфейсы.

Ответ 4

Метод, реализованный с помощью SomeClass, может иметь ту же подпись, что и в интерфейсе, но поскольку он не наследует/не реализует интерфейс, нет способа использовать приведение в этом сценарии - нет "случайных" соответствие - вы должны явно для каждого класса, чтобы он реализовал конкретный интерфейс.

Ответ 5

CSScriptLibrary.dll имеет метод расширения, который "выравнивает" экземпляр объекта к данному интерфейсу:

public static T AlignToInterface<T>(this object obj) where T : class;

Также проверьте остальную часть библиотеки, это действительно полезный API, когда дело доходит до отражения сценариев на С#.

С уважением.