我开发了一个远程类,用于替换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方式,但都会对性能产生影响。
答案 0 :(得分:2)
int?
的拳击规则确实意味着一旦你将其作为object
,你就会看到:
null
,无法再识别(int)5
(int?)5
和object
完全相同的外观
因此,可用的选项:
MethodInfo
,然后使用MethodInfo.Invoke
(这样可以确保参数不会产生歧义)就个人而言,我对这些事情有一个非常简单的看法......而不是试图编码模糊的多参数方法,另一个选择是简化总是传递单个,DTO基于参数 - 即代替SetUsageID(int?)
你可以SetUsage(SetUsageArgs)
(或类似的东西),其中SetUsageArgs
恰好有一个属性。重点是:你现在只是编码一个DTO,一旦你反序列化了DTO就没有歧义。