3

我在 Unity3D 项目中使用LitJsonBestHTTP库,我会编写我的自定义ResponseSerializer对象。目标是创建一个使用泛型将可能的响应映射到我想要的对象的方法。

所以,我的第一次尝试是类似的:

public static void SerializeResponse<T>(string error, HTTPResponse response, string insideKey, Action<APIResource<T>> callback)
    where T:new()
{
    var apiResource = new APIResource<T>();

    if (error != null)
    {
        apiResource.error = error;
    }
    else
    {
        apiResource.error = null;
        JsonData jsonData = JsonMapper.ToObject(response.DataAsText);
        apiResource.resource = (T)(jsonData[insideKey]);
    }
    callback(apiResource);
}

但是通过这种方式,我得到了编译错误

apiResource.resource = (T)(jsonData[insideKey]);

带有消息:

无法将类型转换LitJson.JsonDataT

所需T的可能类型只有 4 种(目前):

  • 细绳
  • 整数
  • 漂浮
  • 布尔

所以,我开始玩开关类型,但每次我得到编译错误。我的最后一次尝试是这个(取自https://stackoverflow.com/a/4478535/2838073):

public static void SerializeResponse<T>(string error, HTTPResponse response, string insideKey, Action<APIResource<T>> callback)
    where T:new()
{
    var apiResource = new APIResource<T>();

    if (error != null)
    {
        apiResource.error = error;
    }
    else
    {
        apiResource.error = null;
        JsonData jsonData = JsonMapper.ToObject(response.DataAsText);

        var @switch = new Dictionary<Type, Action> {
            { typeof(string),   () => { apiResource.resource = (string)jsonData[insideKey]; } },
            { typeof(int),      () => { apiResource.resource = (int)jsonData[insideKey]; } },
            { typeof(float),    () => { apiResource.resource = (float)jsonData[insideKey]; } },
            { typeof(bool),     () => { apiResource.resource = (bool)jsonData[insideKey]; }}
        };

        @switch[typeof(T)]();
    }
    callback(apiResource);
}

但错误总是一样的:

无法将类型隐式转换mytypeT

我究竟做错了什么?我对带有泛型模式的 C# 不实用,我会从我的错误中吸取教训。

4

2 回答 2

2

由于T包括值类型(例如int)和引用类型(string),您需要将之前返回的值jsonData[insideKey]转换为object

apiResource.resource = (T)(object)(jsonData[insideKey]);
于 2017-10-02T10:16:36.627 回答
0

这样的事情不是很好吗?我使用了您的第一个代码,但它不是类型转换,而是创建一个新的 json 字符串,并将使用通用 ToObject 尝试创建最终对象:

public static void SerializeResponse<T>(string error, HTTPResponse response, string insideKey, Action<APIResource<T>> callback) where T : new()
{
    var apiResource = new APIResource<T>();

    if (error != null)
    {
        apiResource.error = error;
    }
    else
    {
        apiResource.error = null;
        JsonData jsonData = JsonMapper.ToObject(response.DataAsText);
        apiResource.resource = JsonMapper.ToObject<T>(jsonData[insideKey].ToJson());
    }
    callback(apiResource);
}

不幸的是,这是一个额外的 object->json string->object 转换,我想。但至少它应该工作。

于 2017-10-02T14:36:13.563 回答