Вопрос про наследование в C#

Господа, я запутался в трех соснах.

Я хочу

  1. написать базовый класс, в котром есть метод - void MyMethod()

  2. Использовать его в унаследованных классах, не меняя их код и вообще не создавая в классах - наследниках ничего похожего на void MyMethod(){...}

Но, похоже, я чего то не понимаю.

Если я напишу вот такую "заготовку"

    public interface IMyBase {
        void MyMethod();
    }
    
    public class MyBaseClass : IMyBase {
        public void MyMethod() {
            Debug.Print($"Hi from MyMethod()!");
        }
    }

и потом попробую в каком то другом классе унаследоваться от IMyBase - это приведёт к тому, что мне необходимо будет написать реализацию метода MyMethod(). А я хочу этого избежать :-)

То есть, если я пишу

    class WorkClass : IMyBase {

    }

то я получаю ошибку "метод не имплементирован". И от меня ожидается, что я напишу реализацию MyMethod() внутри класса WorkClass. А я хочу этого как раз избежать: написал в одном месте - и в коде WorkClass хотел бы просто вызвать по имени метод MyMethod, и чтобы при этом отработал код, который уже написан в MyBaseClass.

К сожалению, наследоваться от класса MyBaseClass в рабочем классе WorkClass я не могу: в настоящем коде у меня WorkClass уже наследуется от Form, а наследоваться от двух классов нельзя.

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

Не могли бы вы мне дать совет?

Спасибо.


Ответы (2 шт):

Автор решения: Алексей Шиманский

Вы сделали базовый класс для наследников, соответственно надо от него и наследоваться:

class WorkClass : MyBaseClass {

}

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

→ Ссылка
Автор решения: aepot

Для .NET Framework для вашей задачи нет решения, ну если только унаследовать базовый класс от вашей новой абстракции. А вот для .NET Core 3.1/.NET 5 - есть.

Default Interface Methods

public class Program
{
    public static void Main()
    {
        IMyBase myClass = new MyClass();
        myClass.MyMethod();
    }
}

class MyClass : MainBase, IMyBase
{
        
}

class MainBase
{

}

interface IMyBase
{
    public void MyMethod()
    {
        Console.WriteLine($"Hi from MyMethod()!");
    }
}

Кажется, работает

Hi from MyMethod()!

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

→ Ссылка