Можно ли по-настоящему «запечатать» функцию класса, чтобы ее нельзя было каким-либо образом переопределить в подклассах?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Можно ли по-настоящему «запечатать» функцию класса, чтобы ее нельзя было каким-либо образом переопределить в подклассах?

Сообщение Anonymous »

Основной вопрос, объясненный с помощью кода:
Скажем, у меня есть интерфейс
public interface IWorker
{
void DoWork();
}

Теперь настройте абстрактный класс, реализующий этот интерфейс. Я хочу, чтобы логика функции DoWork() этого абстрактного класса была ЕДИНСТВЕННОЙ возможной реализацией этой функции. Подклассы этого абстрактного класса НЕ ДОЛЖНЫ иметь возможность переопределять эту функциональность. Вместо этого они вынуждены предоставлять некоторые «вспомогательные» функции для помощи в реализации DoWork():
public abstract class AbstractWorker : IWorker
{
// I cannot force this to be "sealed" - sealed keyword cannot be applied. All subclass's
// could override this logic if they wanted to
public void DoWork()
{
if (ShouldProcess()) Process();
}

public abstract bool ShouldProcess();
public abstract void Process();
}

public class Worker : AbstractWorker
{
// I DON'T want this to be possible - overriding this implementation.
// I want forced usage of the abstract class implementation.
public new void DoWork()
{
// Look at me, I'm going to decide to deviate away from my base class implementation
}
public override bool ShouldProcess() => true;
public override void Process() => Console.WriteLine("Processed");
}

// Consumer code
public void SomeFunction()
{
IWorker worker = GetWorkerSomehow();
// I want this to always use the abstract class implementation
// regardless of what concrete class I get back here.
worker.DoWork();
}

Я хочу, чтобы любой вызов объекта с интерфейсом IWorker ВСЕГДА использовал логику реализации абстрактного класса и вместо этого делегировал фактическую обработку через абстрактные функции, которые должны реализовать подклассы. Кажется, невозможно вызвать ошибки компиляции, если подкласс решит переопределить класс DoWork(). Они всегда могут сделать это с помощью оператора new в сигнатуре функции.
Пример из реальной жизни, поскольку я знаю, что люди могут сказать, что я пытаюсь сделать что-то непреднамеренное и должен это сделать. ищите другую стратегию реализации (и, возможно, так и есть). Я хочу реализовать шаблон проектирования «Цепочка ответственности». В этом шаблоне используется абстрактный класс, который реализуют конкретные классы, чтобы шаблон работал. Эти конкретные классы должны либо принять решение об обработке запроса, либо, если это невозможно, вызвать следующий обработчик запроса. Но реализации этой идеи нет. Кто-то может создать новый конкретный класс и просто забыть переслать вызов следующему обработчику, разрывая цепочку. Мне нужна принудительная гарантия того, что шаблон всегда будет соблюдаться во всех конкретных классах.
Код:
public interface IHandler
{
void HandleRequest();
IHandler SetNextHandler(IHandler nextHandler);
}

public abstract class AbstractHandler : IHandler
{
private readonly IHandler _nextHandler;

public IHandler SetNextHandler(IHandler nextHandler);
{
_nextHandler = nextHandler;
return nextHandler;
}

// Forced calling of the _nextHandler if applicable
public void HandleRequest()
{
if (CanHandleRequest()) ProcessRequest();
else if (_nextHandler is not null) _nextHandler.HandleRequest();
}

// Forced function implementations on the concrete classes
// that aids in the HandleRequest() process
public abstract bool CanHandleRequest();
public abstract void ProcessRequest();
}

public class GoodHandler : AbstractHandler
{
public override bool CanHandleRequest() => true;
public override void ProcessRequest() { // Do stuff }
}

public class BadHandler : AbstractHandler
{
// Don't want this override via the 'new' keyword to be possible....should only use
// the abstract class implementation
public new void HandleRequest()
{
if (CanHandleRequest()) ProcessRequest();
// Look, I don't decide to forward the request to nextHandler, chain is broken
// I must rely on future class creators to fully understand this concept.
}
public override bool CanHandleRequest() => false;
public override void ProcessRequest() { // Do stuff }
}

// Consumer code
public void SomeFunction()
{
IHandler good = new GoodHandler();
IHandler bad = new BadHandler();

bad.SetNextHandler(good);

bad.HandleRequest(); // We will never call to the "good" handler
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... dden-in-su
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»