Фабрика Веселья c Делегат - PullRequest
0 голосов
/ 09 марта 2020

Я пытаюсь найти способ, с помощью которого я мог бы получить бизнес-функцию в качестве удовольствия c. Я пытаюсь написать бизнес-логику c как чистую функцию, чтобы в зависимости от требований мой провайдер или фабрика могли вернуть мне только ту часть бизнес-логики c, а не весь объект, в котором есть методы, которые мне не нужны для определенного кода logi c flow.

public static Func<IArgs, IOut> GetFunc()
{
    return new Func<IArgs, IOut>((DataParams p) => new OutObject());
}

Проблема в том, что, хотя DataParams и OutObject реализуют IArgs и IOut, компилятор предупреждает меня о неявной ошибке приведения. Создание ковариантных интерфейсов с T затрудняет мне понять, как мне это реализовать.

Основная цель - я хочу написать фабрику, которая выбрасывает функции, которые принимают объекты (более производные типы), содержащие другой набор параметров, которые будут переданы в качестве свойств Get-Set. Эта функция возвращает мне объект после обработки данных на основе переданного параметра. Я хочу, чтобы потребитель знал, какой объект производного типа функция ожидает в качестве параметра.

public static Func<IArgs, IOut> GetFunc(processor p)
{
    Func<IArgs, IOut> f = default;
    switch (p)
    {
        case processor.DoWork:
            f = (p) => new OutObject(); //P is cat derived from IArgs
            break;


        case processor.FooWork:
            f = (p) => new SomeOutObject(); //P is dog derived from IArgs
            break;
      }
      return f;
 }

1 Ответ

0 голосов
/ 10 марта 2020

Просмотрите код ниже, это, на мой взгляд, похоже на то, что вы пытаетесь:

namespace LibGeneric
{
    public interface IArgs {  }     

    public interface IOut { }

     public class LibClassGeneric<TArgs,TOut>
     where TArgs:IArgs
     where TOut:IOut
     {
            public static Func<TArgs,TOut> GetFunc()
            {
                return (DataParams p) => new OutObject();
            }

    }

    public class DataParams : IArgs  { }

    public class OutObject : IOut  { }

}

Следующая строка является ошибкой компиляции по следующей причине:

return (DataParams p) => new OutObject();

  • Нет совместимости типов между TArgs, DataParams и TOut,OutObject
  • Что вы пытаетесь сделать, если базовый интерфейс или класс одинаковы, то два типа могут быть назначены другим , что неверно
  • Для функции Generi c / Fun c Делегат для компиляции вам нужно присвоить ему что-то, что принимает TArgs в качестве ввода и TOut в качестве вывода, теперь они имеют ограничения, которые необходимо проверить, что вы не можете добавить какой-либо код во время компиляции, который не соответствует ограничению.
  • Только при вызове Func<TArgs,TOut> GetFunc() вы сможете заполнить DataParams и OutObject, не при определении универсального c определения

Теперь рассмотрим это определение кода Generi c:

public class LibClassGeneric<TArgs,TOut>
     where TArgs:IArgs
     where TOut:IOut
     {
             public static Func<TArgs,TOut> GetFunc(TOut o)
             {
               return (args) => o;
             }        
    }
  • Это скомпилируется, так как вы референт вернитесь к правильным типам в определении метода
  • Вот как вы можете его использовать:

     DataParams d = new DataParams();
     OutObject o = new OutObject();
     var resultFunc  = LibClassGeneric<DataParams,OutObject>.GetFunc(o); // Call Func
     resultFunc(d); // Invocation
    
  • Теперь вы добавляете любой уровень сложности при вызове и вызывая GetFunc(), пока параметр типа точки не совпадет с

Редактировать 1:

Ниже приведен код предоставлено OP:

public static Func<IArgs, IOut> GetFunc(Processor p)
        {

        Func<IArgs, IOut> f = default;

        switch (p)
        {
            case Processor.DoWork:
                f = (p) => new OutObject(); //P is cat derived from IArgs
                break;


            case Processor.FooWork:
                f = (p) => new OutObject(); //P is dog derived from IArgs
                break;
            }
            return f;
        }

Этот код возвращает забавный делегат c с IArgs в качестве входных данных и IOut в качестве выходных данных, что, будучи совместимым с Contravariant и Covariant, позволяет предоставлять параметр как производный класс IArgs и результат может быть производным классом IOut, его можно просто вызвать с помощью вызова следующим образом:

  var func = GetFunc(Processor.DoWork);
  var result = func(new Dog());

Теперь тип result равен IOut и нуждается в приведении типа к фактическому типа, нет никакого способа изменить его, кроме исследования точного типа с помощью отражения или выполнения приведения типа * stati c

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