gpt4 book ai didi

c# - 带有可为空参数的 Type.InvokeMember

转载 作者:太空宇宙 更新时间:2023-11-03 11:23:04 25 4
gpt4 key购买 nike

项目

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

它现在适用于所有类型(包括将使用我多年前编写的自己的序列化器序列化的复杂类型)并且它还能够处理复杂情况(A 调用 B,B 调用 A,A 返回一些东西,B 返回东西)。

方法调用

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

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 而不是一个可以为 null 的了。我正在序列化参数并在目标机器上反序列化它们。此时我正在调用 Type.InvokeMethod 这会导致异常,因为他找不到将 Int32 作为第一个参数的方法(第二个当不忽略它时) .

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

最佳答案

int? 的装箱规则确实意味着一旦你将它作为 object你看:

  • 值为 null , 再也看不到了
  • 非空 值仅称为不可空类型
    • 具体来说,通过 (int)5(int?)5object 中具有完全相同的外观

因此,可用的选项:

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

不过,就我个人而言,我对此类事情的看法非常简单...与其尝试对模糊的多参数方法进行编码,另一种选择是简化为始终传递单个,DTO -based, parameter - 即代替 SetUsageID(int?)你可以有 SetUsage(SetUsageArgs) (或类似的东西),其中 SetUsageArgs碰巧只有一个属性。重点是:您现在只对单个 DTO 进行编码,一旦反序列化该 DTO 就没有歧义。

关于c# - 带有可为空参数的 Type.InvokeMember,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10277813/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com