Вызов методов расширения базового класса С# из внутреннего производного класса?

Это надуманный пример:

public static class MyExtensions
{
  public static void MyMethod( this MyInterface obj, string txt )
  {
  }
}

interface MyInterface {}

public MyDerived : MyInterface
{
  void DoStuff()
  {
    MyMethod( "test" ); // fails; compiler can't find MyMethod?
  }
}

В моем примере выше я пытаюсь вызвать метод расширения, назначенный интерфейсу из моего производного класса. Компилятор здесь не работает и говорит, что MyMethod не существует в текущем контексте. У меня есть все соответствующие операторы использования в моем файле CS, поэтому я не уверен, что происходит.

Ответ 1

Попробуйте вызвать его как this:

this.MyMethod("test");

Ответ 2

Вот альтернативное решение (предпочитаемое мной):

(this as MyInterface).MyMethod("test");

Почему? - потому что ранее предоставленное решение не будет работать в тех случаях, когда метод расширения вызывает класс "новый" метод (свойство также является методом). В таких случаях вы можете называть метод расширения для типа, объявленного базовым классом/интерфейсом, который может отличаться от производного класса/интерфейса.

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

РЕДАКТИРОВАТЬ: это может быть неуместным, если вы действительно не хотите передавать "базу" в метод расширения и вместо этого разрешать ему принимать "this". Однако вы должны учитывать поведенческие различия.

Также интересно отметить как ответ на комментарий Дарина Димитрова: методы расширения не требуют, чтобы экземпляр запускал их, потому что они являются статическими методами. Вы можете вызвать метод расширения как статический, передав ему параметры. Однако "base" не является допустимым значением параметра для параметра, помеченного "this" в объявлении метода расширения, который (если бы я был MS) позволил бы упростить общее использование методов расширения.

Ответ 3

Попробуйте назвать это следующим образом:

this.MyMethod("test");

Ответ 4

Измените вызов на

this.MyMethod("test")

Этот код компилируется:

public static class MyExtensions
{
  public static void MyMethod( this MyInterface obj, string txt )
  {
  }
}

public interface MyInterface {}

public class MyDerived : MyInterface
{
  void DoStuff()
  {
    this.MyMethod( "test" ); // works now
  }
}