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

C# имеет полезную функцию явного интерфейса, которая позволяет создавать методы, реализующие интерфейсы, избегая возможных конфликтов имен.

public abstract class BaseClass : IDisposable {
  public int Value;
  void IDisposable.Dispose() => Value = 1;
}

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

public class SubClass : BaseClass, IDisposable {
  void IDisposable.Dispose() => Value = 2;
}

static void Main() {
  BaseClass obj = new SubClass();
  ((IDisposable)obj).Dispose();
  Console.WriteLine(obj.Value); // 2
}

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

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


person benjamin.popp    schedule 25.05.2017    source источник
comment
Вы не можете получить доступ к переопределенному методу без разрешения подкласса. Может быть, через какое-то сумасшедшее отражение. Больший вопрос в том, почему вы хотите. Это в основном нарушение наследования.   -  person Yuriy Faktorovich    schedule 25.05.2017
comment
Там stackoverflow.com/questions/7090122/ Вам также даются некоторые обходные пути.   -  person Wiktor Zychla    schedule 25.05.2017
comment
Юрий, в настоящее время я использую явные интерфейсы, чтобы разрешить строгие возвращаемые типы в подклассах. Я не дошел до точки, где мне нужно вызвать реализацию базового класса. Но я хотел знать, возможно ли это.   -  person benjamin.popp    schedule 25.05.2017
comment
Явная реализация интерфейса бесполезна, это неизбежное зло. Если класс реализует ICowboy и IPainter, то его метод Draw() не может разумно одновременно стрелять из пистолета и наносить краску. Вы должны сделать один из интерфейсов жертвой и реализовать его метод Draw() с явной реализацией интерфейса. Так что используйте его только тогда, когда вам нужно. И когда вы это сделаете, вы должны привести this к (интерфейсу), чтобы вы могли вызвать правильный метод.   -  person Hans Passant    schedule 25.05.2017


Ответы (1)


Я надеюсь, что это будет полезно:

 public abstract class BaseClass : IDisposable
 {
        public int Value;
        void IDisposable.Dispose() => DoSomething();
        public void DoSomething() => Value = 1;
 }

 public class SubClass : BaseClass, IDisposable
 {
        void IDisposable.Dispose()
        {
            if (Condition())
                DoSomething();
            else
                DoSomethingElse();
        }

        void DoSomethingElse() => Value = 2;

        private bool Condition()
        {
            return true;
        }


 }
person Saeid    schedule 25.05.2017
comment
Что я получаю из этого, так это то, что явная реализация базового класса в основном должна просто пересылать другой метод, по крайней мере, с защищенной видимостью. Но по-прежнему нет способа вызвать базовый метод, вам просто нужно вызвать метод пересылки. Тем не менее, это лучше, чем ничего. - person benjamin.popp; 25.05.2017
comment
@benjamin.popp Невозможно вызвать базовый метод, это против наследования. - person Saeid; 25.05.2017