Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.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# 如何在强类型接口上引用方法名_C#_Reflection_Interface_Strongly Typed View_Strong Typing - Fatal编程技术网

C# 如何在强类型接口上引用方法名

C# 如何在强类型接口上引用方法名,c#,reflection,interface,strongly-typed-view,strong-typing,C#,Reflection,Interface,Strongly Typed View,Strong Typing,很抱歉,如果这个问题已经得到了回答,但我认为我实际上缺乏正式的教育来正确地提出这个问题,因此也缺乏正确的标准来成功地寻找它 我有一个API,它有几个调用,它们做几乎相同的事情,但使用不同的方法对不同的输入对象进行操作,但总是形成相同的接口。我想将剪切粘贴方面从API方法调用过程中去掉,以便在所有方法调用中完成相同的公共代码。我已经设法为输入和输出对象使用泛型获得了一个有效的解决方案,并且正在引用要从字符串调用的方法名。我希望对方法的引用是强类型的,而不是基于字符串的,这样在重新分解时重命名方法名

很抱歉,如果这个问题已经得到了回答,但我认为我实际上缺乏正式的教育来正确地提出这个问题,因此也缺乏正确的标准来成功地寻找它

我有一个API,它有几个调用,它们做几乎相同的事情,但使用不同的方法对不同的输入对象进行操作,但总是形成相同的接口。我想将剪切粘贴方面从API方法调用过程中去掉,以便在所有方法调用中完成相同的公共代码。我已经设法为输入和输出对象使用泛型获得了一个有效的解决方案,并且正在引用要从字符串调用的方法名。我希望对方法的引用是强类型的,而不是基于字符串的,这样在重新分解时重命名方法名就不会让方法名的“神奇”字符串在运行时等待爆炸

下面是我试图实现的一个非常简化的版本

class ARequest { };
class AResponse { };
class BRequest { };
class BResponse { };

interface IWorker
{
    AResponse DoA(ARequest aRequest);
    BResponse DoB(BRequest bRequest);
}
class Worker : IWorker
{
    public AResponse DoA(ARequest aRequest)
    {
        return new AResponse();
    }
    public BResponse DoB(BRequest bRequest)
    {
        return new BResponse();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // current concrete copy & paste implementation
        var a1 = API.DoA(new ARequest { });
        var b1 = API.DoB(new BRequest { });
        // new generic implementation
        var a2 = API.DoA2(new ARequest { });
        var b2 = API.DoB2(new BRequest { });
    }
}

static class API
{
    // current concrete copy & paste implementation
    public static AResponse DoA(ARequest aRequest)
    {
        // lots of common code for logging & preperation
        var worker = GetWorker();
        return worker.DoA(aRequest);
    }
    public static BResponse DoB(BRequest bRequest)
    {
        // lots of common code for logging & preperation
        var worker = GetWorker();
        return worker.DoB(bRequest);
    }
    private static IWorker GetWorker()
    {
        return new Worker();
    }
    // new generic implementation Attempt
    public static AResponse DoA2(ARequest aRequest)
    {
        return DoGen<ARequest, AResponse>(aRequest, "DoA"); // how to make references to DoA and DoB methods on the IWorker strongly typed?
    }
    public static BResponse DoB2(BRequest bRequest)
    {
        return DoGen<BRequest, BResponse>(bRequest, "DoB"); // how to make references to DoA and DoB methods on the IWorker strongly typed?
    }
    public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, string methodname)
        where TRequest : class
        where TResponse : class
    {
        // lots of common code for logging & preperation
        var worker = GetWorker();
        var mi = worker.GetType().GetMethod(methodname);
        var result = mi.Invoke(worker, new Object[] { requestObj });
        return result as TResponse;
    }

}
class-ARequest{};
类AResponse{};
类BRequest{};
类b响应{};
接口IWorker
{
AResponse-DoA(ARequest-ARequest);
Bressponse-DoB(BRequest-BRequest);
}
班主任:IWorker
{
公共AresResponse DoA(ARequest ARequest)
{
返回新的AResponse();
}
公共响应DoB(BRequest-BRequest)
{
返回新的b响应();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
//当前的具体复制和粘贴实现
var a1=API.DoA(新的ARequest{});
var b1=API.DoB(新BRequest{});
//新的通用实现
var a2=API.DoA2(新的ARequest{});
var b2=API.DoB2(新BRequest{});
}
}
静态类API
{
//当前的具体复制和粘贴实现
公共静态AresResponse DoA(ARequest ARequest)
{
//许多用于日志记录和准备操作的通用代码
var-worker=GetWorker();
返回工人.DoA(aRequest);
}
公共静态响应DoB(BRequest-BRequest)
{
//许多用于日志记录和准备操作的通用代码
var-worker=GetWorker();
返回工人。DoB(布雷奎斯特);
}
私有静态IWorker GetWorker()
{
返回新工人();
}
//新的通用实现尝试
公共静态AresResponse DoA2(ARequest ARequest)
{
return DoGen(aRequest,“DoA”);//如何在IWorker强类型上引用DoA和DoB方法?
}
公共静态响应DoB2(BRequest-BRequest)
{
return DoGen(bRequest,“DoB”);//如何在IWorker强类型上引用DoA和DoB方法?
}
公共静态响应DoGen(TRequest requestObj,string methodname)
特雷奎斯特:课堂在哪里
在哪里响应:类
{
//许多用于日志记录和准备操作的通用代码
var-worker=GetWorker();
var mi=worker.GetType().GetMethod(methodname);
var result=mi.Invoke(worker,新对象[]{requestObj});
返回结果作为响应;
}
}

Func可能会满足您的需求:

        var a1 = new Func<ARequest, AResponse>(API.DoA);
        var b1 = new Func<BRequest, BResponse>(API.DoB);
        var a2 = new Func<ARequest, AResponse>(API.DoA2);
        var b2 = new Func<BRequest, BResponse>(API.DoB2);
        a1.Invoke(new ARequest { });
        b1.Invoke(new BRequest { });
        a2.Invoke(new ARequest { });
        b2.Invoke(new ARequest { }); // fails at compile time
var a1=新函数(API.DoA);
变量b1=新函数(API.DoB);
var a2=新函数(API.DoA2);
变量b2=新函数(API.DoB2);
a1.调用(新请求{});
b1.调用(新的BRequest{});
a2.调用(新请求{});
b2.调用(新的ARequest{});//在编译时失败

为方法添加一名代表:

    public delegate TResponse DoXDelegate<in TRequest, out TResponse>(TRequest request);

    public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, DoXDelegate<TRequest, TResponse> method)
        where TRequest : class
        where TResponse : class
    {
        // lots of common code for logging & preperation
        var worker = GetWorker();
        /*var mi = worker.GetType().GetMethod(methodname);
        var result = mi.Invoke(worker, new Object[] { requestObj });
        return result as TResponse;*/
        return method.Invoke(requestObj);
    }
public委托响应DoXDelegate(TRequest请求);
公共静态响应DoGen(TRequest-requestObj,DoXDelegate方法)
特雷奎斯特:课堂在哪里
在哪里响应:类
{
//许多用于日志记录和准备操作的通用代码
var-worker=GetWorker();
/*var mi=worker.GetType().GetMethod(methodname);
var result=mi.Invoke(worker,新对象[]{requestObj});
返回结果作为响应*/
返回方法.Invoke(requestObj);
}
像这样使用
Func

编辑:该解决方案示例仅在工作者对象来自何处无关紧要的情况下可用

// new generic implementation Attempt
public static AResponse DoA2(ARequest aRequest)
{
  return DoGen<ARequest, AResponse>(aRequest, DoA); // how to make refreces to DoA and DoB methods strongly typed?
}

public static BResponse DoB2(BRequest bRequest)
{
  return DoGen<BRequest, BResponse>(bRequest, DoB); // how to make refreces to DoA and DoB methods strongly typed?
}

public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, Func<TRequest, TResponse> func)
  where TRequest : class
  where TResponse : class
{
  // lots of common code for logging & preperation
  var result = func(requestObj);
  return result as TResponse;
}
//新的通用实现尝试
公共静态AresResponse DoA2(ARequest ARequest)
{
return DoGen(aRequest,DoA);//如何使DoA和DoB方法的引用强类型化?
}
公共静态响应DoB2(BRequest-BRequest)
{
return DoGen(bRequest,DoB);//如何使DoA和DoB方法的引用强类型化?
}
公共静态响应DoGen(TRequest requestObj,Func Func)
特雷奎斯特:课堂在哪里
在哪里响应:类
{
//许多用于日志记录和准备操作的通用代码
var结果=func(requestObj);
返回结果作为响应;
}
方法名称的“魔法”字符串更改为委托上的委托

  public static AResponse DoA2(ARequest aRequest)
  {
    return DoGen<ARequest, AResponse>(aRequest, worker => worker.DoA);
  }
  public static BResponse DoB2(BRequest bRequest)
  {
    return DoGen<BRequest, BResponse>(bRequest, worker => worker.DoB); 
  }
  public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, 
       Func<IWorker, Func<TRequest, TResponse>> methodRef)
    where TRequest : class
    where TResponse : class
  {
    // lots of common code for logging & preparation 
    var worker = GetWorker();
    var method = methodRef(worker);

    return method(requestObj);
  }
公共静态AresResponse DoA2(ARequest ARequest)
{
返回DoGen(aRequest,worker=>worker.DoA);
}
公共静态响应DoB2(BRequest-BRequest)
{
返回DoGen(bRequest,worker=>worker.DoB);
}
公共静态响应DoGen(TRequest requestObj,
Func methodRef)
特雷奎斯特:课堂在哪里
在哪里响应:类
{
//许多用于记录和准备的通用代码
var-worker=GetWorker();
var方法=methodRef(工人);
返回方法(requestObj);
}

响应类型是否以任何方式相关?看看这篇博文,它描述了一个满足您需要的模型:Foo42:在最终实现中,它们有一些来自公共基类的公共字段。在这个例子中,它们是没有关联的,也就是说(据我所知),它们正是我想要的。现在我只需要知道它在做什么。我想是时候停止回避函子了。那不是使用API的DoA和DoB方法,而不是worker对象上的方法吗?理想的效果是调用这些方法