2

项目

我开发了一个远程处理类,用于替换 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这会导致异常,因为他找不到将 aInt32作为第一个参数的方法(第二个当不忽略此参数时)。

这个问题的最佳解决方案是什么?有多种方法,但都会对性能产生影响。

4

1 回答 1

2

拳击规则int?确实意味着一旦你拥有它,object你就会看到:

  • 值是null, 什么也看不出来
  • 非空值仅被称为不可为空的类型
    • 所以具体来说,通过(int)5并在内部(int?)5具有完全相同的外观object

因此,可用的选项:

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

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

于 2012-04-23T09:36:31.657 回答