【问题标题】:How to call generic function in dynamic proxy by C#如何通过 C# 在动态代理中调用泛型函数
【发布时间】:2015-08-26 02:17:55
【问题描述】:

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的类的invoke body中调用函数,如何才能达到与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

【问题讨论】:

  • Java 到 c# 工具:codecall.net/2014/03/27/…
  • 您的问题是什么?我不明白你想要达到什么目的。 “但是第二个应该从methodCall判断”是什么意思?这听起来像是一个 XY 问题,而您还没有告诉我们 X 是什么或整个问题是什么,或者您是如何实现 X 的,所以我无法弄清楚您希望如何将 Y 放入解决方案中。继承 RealProxy 的整个类在做什么?
  • 感谢工具推荐。我试过了,它只是简单地翻译了一些简单的特性,但无法处理通用/动态代理等复杂条件

标签: c# generics dynamic-proxy


【解决方案1】:

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 更明确,以便为类型推断提供足够的上下文,或利用其他数据类型来重写代码(动态、字典等)。

【讨论】:

    【解决方案2】:

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

    public interface IRequest<TResponse>
    {
    
    }
    
    public class GetRealTimeQueryDataRequest : IRequest<GetRealTimeQueryDataResponse> {}
    

    从那里您可以使用.GetType().GetInterfaces() 通过过滤“是typeof(IRequest&lt;&gt;)”来获得IRequest&lt;GetRealTimeQueryDataResponse&gt;。那么只需要获取IRequest&lt;GetRealTimeQueryDataResponse&gt;的泛型类型参数即可。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-13
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      相关资源
      最近更新 更多