Возьмите класс, который реализует интерфейс - PullRequest
0 голосов
/ 08 января 2020

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

Вот пример базового класса, интерфейса и производного класса:

public abstract class ModelBase
{
    public ModelBase(string name) 
    {
        Name = name;
    }

    public int Id { get; private set; }

    public int Name { get; private set; }
}


public interface ISupportProcessA
{
    public decimal Amount { get; }
}


public class ModelDerived : ModelBase
{
    public ModelDerived(string name) : base(name) { }

    public decimal Amount { get; private set; }
}

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

public abstract class ProcessorBase
{
    private readonly ModelBase model;

    public ProcessorBase(ModelBase model)
    {
        this.model = model;
    }

    // ...some shared methods
 }


 public class ProcessorA : ProcessorBase 
 {
     private readonly ISupportProcessA model;

     public ProcessorA(ISupportProcessA model) : base(model)
     {
         this.model = model;
     }

     // ...some specific methods
 }

Теперь здесь кроется проблема. Потому что ISupportProcessA не относится (к знанию компиляторов) к ModelBase и поэтому не может быть задано в качестве ввода в base(). В этом есть смысл.

Итак, я попытался создать интерфейс IModelBase, который я использую вместо ModelBase. Однако после подключения к Entity Framework возникают некоторые проблемы, которые плохо работают с интерфейсами (или, может быть, это только у меня?).

Итак, вот мой вопрос:

Есть ли в любом случае, запросить класс, который получает из ModelBase, но также реализует ISupportProcessA?

1 Ответ

2 голосов
/ 08 января 2020

Вы можете получить кое-что с дженериками:

public class ProcessorA<TModel> : ProcessorBase where TModel : ModelBase, ISupportProcessA
{
    private readonly ISupportProcessA model;

    public ProcessorA(TModel model) : base(model)
    {
        this.model = model;
    }

    // ...some specific methods
}

Однако это немного уродливо, поскольку вам нужно создать новый ProcessorA<ModelDerived>, а не просто ProcessorA.


Вы можете добавить больше шаблонов, чтобы сделать вещи немного лучше:

public abstract class ProcessorBase
{
    protected abstract ModelBase ModelForBase { get; }


    // ...some shared methods
}

public abstract class ProcessorA : ProcessorBase
{
    public static ProcessorA Create<TModel>(TModel model) where TModel : ModelBase, ISupportProcessA
    {
        return new ProcessorA<TModel>(model);
    }

    // Abstract specific methods
    public abstract void SomeSpecificMethod();
}


public class ProcessorA<TModel> : ProcessorA where TModel : ModelBase, ISupportProcessA
{
    protected override ModelBase ModelForBase => model;

    private readonly TModel model;

    public ProcessorA(TModel model)
    {
        this.model = model;
    }

    // Specific method overrides
    public override void SomeSpecificMethod()
    {
    }
}

Это означает, что вы можете сделать ProcessorA processor = ProcessorA.Create(new Model()), но за счет гораздо большего количества шаблонов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...