Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Func委托工厂_C#_Function_Design Patterns_Lambda_Architecture - Fatal编程技术网

C# Func委托工厂

C# Func委托工厂,c#,function,design-patterns,lambda,architecture,C#,Function,Design Patterns,Lambda,Architecture,我正在试图找到一种方法,使用它我可以得到一个业务函数作为Func。我试图将业务逻辑作为一个纯函数来编写,以便根据需求,我的提供者或工厂可以只返回业务逻辑的一部分,而不是返回具有特定代码逻辑流不需要的方法的整个对象 public static Func<IArgs, IOut> GetFunc() { return new Func<IArgs, IOut>((DataParams p) => new OutObject()); } public stati

我正在试图找到一种方法,使用它我可以得到一个业务函数作为Func。我试图将业务逻辑作为一个纯函数来编写,以便根据需求,我的提供者或工厂可以只返回业务逻辑的一部分,而不是返回具有特定代码逻辑流不需要的方法的整个对象

public static Func<IArgs, IOut> GetFunc()
{
    return new Func<IArgs, IOut>((DataParams p) => new OutObject());
}
public static Func GetFunc()
{
返回newfunc((DataParams p)=>newoutobject());
}
问题是,即使DataParams和OutObject正在实现IARG和IOut,编译器也会警告我隐式转换错误。使接口与变量协变使我很难弄清楚应该如何实现它

主要目标-我想编写一个工厂,它抛出将持有不同参数集的对象(更多派生类型)作为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;
 }
public static Func GetFunc(处理器p)
{
Func f=默认值;
开关(p)
{
case processor.DoWork:
f=(p)=>newoutobject();//p是从IARG派生的cat
打破
case processor.FooWork:
f=(p)=>newsomeoutobject();//p是从IARG派生的狗
打破
}
返回f;
}

查看下面的代码,我认为这与您正在尝试的类似:

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  { }

}
  • 这将编译,因为您在方法定义中引用了正确的类型
  • 这是您如何利用它的:

     DataParams d = new DataParams();
     OutObject o = new OutObject();
     var resultFunc  = LibClassGeneric<DataParams,OutObject>.GetFunc(o); // Call Func
     resultFunc(d); // Invocation
    
    此代码返回一个func委托,其中,IArgs作为输入,IOut作为输出,它是逆变和协变的,允许提供一个参数作为IArgs的派生类,结果可以是IOut的派生类,可以使用如下调用简单调用:

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

    现在,
    结果
    类型是
    IOut
    并且需要类型转换为实际类型,除了通过反射探测确切类型或进行静态类型转换之外,没有办法更改它

    当前接口是不变的,对函数定义进行以下更改,
    Func
    为了使其符合协变项,警告将被清除,您可以在C#8中执行某些操作吗?在此之前,我认为C#2/C#3引入了协变项这对于代理和接口是可能的。但是,我正在尝试按原样返回函数。希望它有意义。您正在返回一个Func委托,该委托必须是协变量。请理解,在没有委托(函数指针)的情况下无法返回函数。我的原始问题中的Func委托具有特定的接口类型,而不是泛型TArgs,TOut。我已经修改了这个问题,以便更清楚地说明我到底在寻找什么。您编译的代码没有任何问题,这并不能解释您所指的问题,直到您从IARG和IOut获得输入和输出为止。如果要将基类型作为输入参数提供,则将填充任何类型的派生参数,请清楚地解释此问题,在与GetFunc()相同的基础上,没有您前面提到的编译错误,我只想让使用者知道在调用实际函数时需要将什么派生类型对象作为参数传递。看一看问题中添加的代码,这应该会让想法更清晰。您添加的代码没有提供任何附加信息,我甚至不知道现在到底是什么问题,您可以简单地调用
    GetFunc
    ,获取一个func委托作为返回,您可以提供IARG的任何子类,返回的可以是IOut的任何派生类。你们所说的感知是什么意思,在这里,调用方应该只知道哪些是派生类,哪些是委托实现的反向和协方差。如果真的有问题,那么突出显示它,目前我看到没有检查我答案的编辑1,这可能在某种程度上有所帮助,在这种情况下,没有办法避免类型转换
    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;
            }
    
      var func = GetFunc(Processor.DoWork);
      var result = func(new Dog());