使用泛型类型的开关序列化响应

时间:2017-10-02 10:10:14

标签: c# generics unity3d litjson

我在Unity3D项目中使用 LitJson BestHTTP 库,我会编写自定义 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.JsonData类型转换为T

所需的 T 的可能类型仅为4(暂时):

  • 字符串
  • INT
  • BOOL

所以,我开始玩开关类型,但每次我得到编译错误。我的最后一次尝试是(摘自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);
}

但错误总是一样的:

  

无法隐式将mytype类型转换为T

我做错了什么? 我对C#的仿制药模式并不实用,我会从错误中吸取教训。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分: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);
}

不幸的是,这是一个额外的对象 - &gt; json string-&gt;对象转换。但至少它应该有用。