Type.InvokeMember,可以为nullable参数

时间:2012-04-23 09:21:07

标签: c# reflection nullable

项目

我开发了一个远程类,用于替换WCF的子集。之所以这样做是因为我们的目标是使用Unity3D的移动平台,并且需要尽可能减少内存消耗。 (因此我们不需要包含System.ServiceModel,它实际上具有2.7MB的大小,这对于小型移动RAM来说很重要

现在它适用于所有类型(包括将在几年前使用我自己的序列化程序进行序列化的复杂类型)并且它还能够处理复杂情况(A调用B,B调用A,A返回某些内容,B返回某事)。

方法调用

对于在目标站点上调用方法,我使用的Type.InvokeMember实际上适用于除可空类型之外的大多数情况。这就是我遇到的问题。在我的接口定义中,该方法如下所示:

public interface IServerContract 
{
    void SetUsageID(Int32? id);
}

ServerProxy(处理对远程方法的调用的对象)我正在执行以下操作:

public class ServerProxy : ProxyBase
{
    public void SetUsageID(Int32? id)
    {
         RemoteCall("SetUsageID", id);
    }
}

与往常一样,参数id已装箱,因为RemoteCall的定义如下所示:

public void RemoteCall(String methodName, params Object[] arguments) { ... }

此时我只有一个System.Int32而不是可以为空的。我正在序列化参数并在目标机器上反序列化它们。此时我正在调用Type.InvokeMethod,这会导致异常,因为他找不到一个以Int32作为第一个参数的方法(第二个是不忽略这个参数)。

此问题的最佳解决方案是什么?有ser ser方式,但都会对性能产生影响。

1 个答案:

答案 0 :(得分:2)

int?的拳击规则确实意味着一旦你将其作为object,你就会看到:

  • 值为null,无法再识别
  • 非空值仅作为非可空类型而知道
    • 具体而言,在(int)5
    • 中传递(int?)5object 完全相同的外观

因此,可用的选项:

  • 确保方法名称是唯一的,因此您可以按名称唯一地解析为MethodInfo,然后使用MethodInfo.Invoke(这样可以确保参数不会产生歧义)
  • 尝试解决接受非可空类型的方法,然后寻找可空类型(对于多参数方法变得复杂)
  • 传递有关您正在调用的方法的更多元数据(增加大小)

就个人而言,我对这些事情有一个非常简单的看法......而不是试图编码模糊的多参数方法,另一个选择是简化总是传递单个,DTO基于参数 - 即代替SetUsageID(int?)你可以SetUsage(SetUsageArgs)(或类似的东西),其中SetUsageArgs恰好有一个属性。重点是:你现在只是编码一个DTO,一旦你反序列化了DTO就没有歧义。