gpt4 book ai didi

json - 如何存储参数化方法的类型参数,然后使用它们将 JSON 对象转换为泛型类型的普通对象?

转载 作者:行者123 更新时间:2023-12-03 14:54:26 31 4
gpt4 key购买 nike

我正在尝试为 Delphi 和 .NET 编写通用消息传递系统。系统允许将消息定义为普通对象,并将消息处理程序定义为作用于这些对象的匿名方法。

对象被转换为 JSON 并在同一台计算机上运行的应用程序之间传递。每个应用程序都维护一个理解特定消息类型的处理程序列表。

我的类有许多参数化注册方法。有些采用单一类型参数。有些采用一对参数,其中一个代表请求对象,另一个代表响应对象。请求/响应处理程序注册如下所示:

procedure TTelegraph.RegisterRequestHandler<TRequest, TResponse>
(requestTypeToHandle: string; handler: TFunc<TRequest, TResponse>);
begin
FRequestHandlers.Add(requestTypeToHandle,
TRequestHandler<TRequest, TResponse>.Create(handler,
TRequest,
TResponse));
end;

FRequestHandlersTDictionary<string,TRequestHandler> 。注册方法的调用如下:

  FTelegraph.RegisterRequestHandler<TTestRequest, TTestResponse>('My Request', 
function(x: TTestRequest): TTestResponse
begin
Result := TTestResponse.Create;
Result.Number := x.Number;
Result.Message := Format('Received: %s', [x.Message]);
end);

通用TRequestHandler<T1,T2>是一个 DTO,它包装了处理程序以及类型 TRequestTResponse 。它继承自非泛型 TRequestHandler 。我不确定是否有更好的方法来解决这个问题,但这是我能想到的在单个集合中存储多个不相关类型的唯一方法。

这一切似乎都运行良好。问题是当收到请求消息时。处理请求消息的 C# 代码如下所示:

private void ProcessRequestTelegram(Telegram request)
{
var requestType = _RequestHandlers[request.MessageType].RequestType;
var typedRequest = JsonConvert.DeserializeObject(request.Payload, requestType);
var result = _RequestHandlers[request.MessageType].Handler.DynamicInvoke(typedRequest);
var jsonPayload = JsonConvert.SerializeObject(result);
var response = new Telegram()
{
Payload = jsonPayload,
CorrelationID = request.CorrelationID,
Template = TelegramTemplateEnum.Response,
SenderWindowHandle = _LocalWindowHandle.ToInt32(),
RecipientWindowHandle = _MessageRecipient.ToInt32(),
MessageType = request.MessageType
};
var jsonResponse = JsonConvert.SerializeObject(response);

var resultCode = _Messaging.SendMessage(_MessageRecipient, jsonResponse);
CheckIfSendMessageErrorOccurred(resultCode);
}

上面的代码中RequestType属于Type类型。

但是对于我的一生来说,我无法想出与 Delphi 相当的东西。我尝试反序列化 request.Payload ,但我陷入了如何向 JSON 解析器传递类型以将有效负载转换为的问题。我尝试过各种存储方式TRequestTResponseTRequestHandler 的 RequestType 和 ResponseType 属性中:TTypeInfo , TRTTIType目前TClass 。但似乎没有任何东西可以给我任何有用的信息传递给 TJson.JsonToObject 。它有一个通用重载,它采用类型参数作为返回类型,但显然你不能使用 TClass作为类型参数。

最佳答案

您不能使用TJson.JsonToObject<T>因为在调用此方法时,您没有通用的 T。查看此方法的代码,您会发现 T 被传递给 TJSONUnMarshal.CreateObject 。因此,在您的情况下,您应该存储 TClassTRequestTResponse并编写您自己的 TJson.JsonToObject 版本通过 TClass

另一种方法是首先创建实例,然后将其传递给非通用 TJson.JsonToObject这需要 ClassType传递的实例并将其传递给 TJSONUnMarshal.CreateObject .

关于json - 如何存储参数化方法的类型参数,然后使用它们将 JSON 对象转换为泛型类型的普通对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31166789/

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