如何通过C#调用动态代理中的泛型函数

时间:2015-08-26 02:17:55

标签: c# generics dynamic-proxy

java版本: 我的通用功能如下:

public <T, K> JsonEnvelop<T, K> readResponse(Class<T> t, Class<K> k)

一个实现InvocationHandler的类,在invoke函数中,它将调用泛型函数,如下所示:

JsonEnvelop<ResHeader, ?> response = conn.readResponse(ResHeader.class, method.getReturnType());

现在我想要一个C#版本: 然后我翻译泛型函数如下:

public JsonEnvelop<T, K> readResponse<T,K>()

我想在实现RealProxy的类的调用体中调用该函数,如何实现与java版相同的结果?第一个泛型类型可以是ResHeader,但第二个类型应该从methodCall判断,那么如何传递参数K?

public override IMessage Invoke(IMessage msg)
{
    var methodCall = msg as IMethodCallMessage;
    var response = conn.readResponse<ResHeader, Typge.Get(methodCall.TypeName)>(); 
    return new ReturnMessage(response.getBody(), null, 0, methodCall.LogicalCallContext, methodCall);
}

另一个问题是,有没有更好的方法将Java代码翻译成C#?

非常感谢!

感谢Aron,详细问题是:

我有不同的服务,对于每项服务,它都会提供多种功能。每个函数都会发送请求并获得响应。请求和响应因功能和服务而异。设计是使用RealProxy发送请求并获得响应。这里的“public JsonEnvelop readResponse(Class t,Class k)”是获取响应,对于不同的服务和功能,T与ResHeader相同,但K是完全不同的,它依赖于参数。

GetRealTimeQueryDataRequest request = new GetRealTimeQueryDataRequest();
GetRealTimeQueryDataResponse response=reportService.getRealTimeQueryData(request);

以上面为例,它将调用realproxy实现类中的invoke函数,K应该是返回类型GetRealTimeQueryDataResponse

2 个答案:

答案 0 :(得分:0)

C#不像Java那样支持“通配符泛型”。通常,为了解决这个问题,您可以利用C#中称为“泛型类型推理”的功能,其中在调用方法时推断出通用包装函数的类型(有许多旧的SO答案比较这些)。

C#中的一个简单示例是你有一个“?”在Java中:

public T GetItem<T>(ICollection<T> input, int n) {
    return input.ElementAt(n);
}
var items = new List<int>() { 1, 2, 3 };
int secondItem = GetItem(input, 2); // int is inferred  based on generic type of collection item

对于您的示例,您可能需要重新处理方法签名,以便能够为.NET提供足够的上下文来推断Invoke方法的泛型类型。

由于您的特定示例仅使用IMessage作为参数和返回对象,因此泛型类型推理在此处无法直接帮助,并且如上所述,由于缺乏对通用通配符的支持,因此无法将此代码直接转换为C# 。您将不得不探索其他解决方法,例如比IMessage更明确,为类型推断提供足够的上下文来工作或利用其他数据类型来重写代码(动态,字典等)。

答案 1 :(得分:0)

实现特定问题的方法是在界面中定义请求/响应。

public interface IRequest<TResponse>
{

}

public class GetRealTimeQueryDataRequest : IRequest<GetRealTimeQueryDataResponse> {}

通过过滤“.GetType().GetInterfaces()”,您可以使用IRequest<GetRealTimeQueryDataResponse>来获取typeof(IRequest<>)。然后,您只需要获取IRequest<GetRealTimeQueryDataResponse>的泛型类型参数。

然而,实现这一点似乎很奇怪,因为使用依赖注入并获得实现IHandle<GetRealTimeQueryDataRequest>的服务要简单得多。这样你就不需要动态了。