Предоставить реализацию абстрактного метода из интерфейса.C#

Место общения программистов C#
Ответить
Anonymous
 Предоставить реализацию абстрактного метода из интерфейса.

Сообщение Anonymous »

Можно ли переопределить реализацию метода, унаследовав его от интерфейса, который дает реализацию по умолчанию для этого метода? Если нет, то как мне реструктурировать свой код, чтобы избежать явных вызовов методов реализации интерфейса?
Вот обзор структуры классов в моем проекте:

Код: Выделить всё

interface IInputProcessor
{
public ProcessInputsResult ProcessInputs(Item[] inputs);
}

abstract class MachineComponent : IInputProcessor
{
public abstract ProcessInputsResult ProcessInputs(Item[] inputs);
}

interface IComponentContainer where T : MachineComponent
{
public T[] Components { get; }
}

class MachineSystem : MachineComponent, IComponentContainer
{
public MachineComponent[] Components { get; }
}
Моя цель — предоставить реализацию ProcessInputs внутри интерфейса IComponentContainer, поскольку все контейнеры компонентов должны обрабатывать входные данные каждого из своих компонентов, а реализация поскольку это может быть общим для всех производных классов.
Чтобы добиться этого, я попытался создать реализацию метода по умолчанию для ProcessInputs внутри IComponentContainer, например:< /p>

Код: Выделить всё

interface IComponentContainer : IInputProcessor where T : MachineComponent
{
public T[] Components { get; }

ProcessInputsResult IInputProcessor.ProcessInputs(Item[] inputs)
{
...
}
}
Обратите внимание, что я также сделал IComponentContainer производным от IInputProcessor, поскольку все контейнеры компонентов должны обрабатывать входные данные для всех своих компонентов.
Я надеялся, что это новое определение будет означать, что MachineSystem, которая является одновременно MachineComponent и IComponentContainer, не нужно будет указывать реализацию для MachineComponent.ProcessInputs , поскольку это указано в интерфейсе IComponentContainer.
Это было не так, и мне пришлось явно сослаться на метод к реализации, указанной в интерфейсе. вот так:

Код: Выделить всё

class MachineSystem : MachineComponent, IComponentContainer
{
...

public override ProcessInputsResult ProcessInputs(Item[] inputs) =>
((IComponentContainer)this).ProcessInputs(inputs);
}
Я думаю, что это противоречит цели предоставления реализации по умолчанию в интерфейсе, поскольку производные классы должны указывать, что они хотят ее использовать.
Это есть хорошее решение этой проблемы, или мне следует изменить структуру кода?
ОБНОВЛЕНИЕ: В ответ на ответ Ивана Петрова

Код: Выделить всё

interface IComponentContainer : IInputProcessor where T : MachineComponent {
public T[] Components { get; }
}

class ComponentContainer : MachineComponent, IComponentContainer
where T : MachineComponent {
public T[] Components { get; }
public override ProcessInputsResult ProcessInputs(Item[] inputs) {
// implementation will serve for interface method too
}
}

class MachineSystem : ComponentContainer {
// we can still override ProcessInputsResult here too
}
Использование общего базового класса для реализации обработки контейнера компонентов не сработает в моей ситуации, поскольку классы, реализующие IComponentContainer, все являются производными от абстрактного класса MachineComponent > находятся на разных уровнях иерархии классов. Например, MachineSystem : IComponentContainer наследует MachineComponent напрямую, тогда как CompositeComponent : IComponentContainer наследует другой класс SimpleComponent, который, в свою очередь, является производным от MachineComponent. По этой причине использование одного базового класса, от которого все они происходят, наложит на них одну и ту же иерархию. Эту проблему можно было бы легко решить, если бы были возможны общие типы наследования, например:

Код: Выделить всё

class ComponentContainer : TBase, IComponentContainer
where TContainer : MachineComponent
where TBase : MachineComponent
{
public T[] Components { get; }
public override ProcessInputsResult ProcessInputs(Item[] inputs)
{
...
}
}
Но поскольку это не поддерживается, я не вижу способа заставить его работать с общим базовым классом.

Подробнее здесь: https://stackoverflow.com/questions/787 ... -interface
Ответить

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

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

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

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

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