12804


APIの通信部分を作成しており、  
LitJsonを用いてシリアライズとデシリアライズしてデータ送受信しています。

UI側がデータを意識しなくても良いようにキャストする型と  
送信データをobject型でもらい、シリアライズして送信し  
受信データをデシリアライズしてUI側にコールバックで返しています。

LitJsonでデシリアライズする時に、LitJson.JsonMapper.ToObjectメソッドを  
呼ぶ必要があり、<指定した型> の部分に送信元からもらった型を渡したいのですが  
できずに悩んでおります。

string litjsonString = LitJson.JsonMapper.ToJson(送信データ);  
↓  
HTTPリクエスト  
↓  
HTTPレスポンス  
↓  
object data1 = LitJson.JsonMapper.ToObject<指定した型>(受信データ);

■LitJson内の定義

[code]

    public static T ToObject<T>(string json);
    
[/code]

■環境  
Visual Studio 2013 Community  
MonoなのでC#はおそらく3.0  
.NetFrameWork2.0+3.5


CC BY-SA 3.0
2015-07-29T09:31:36.020
12801
2015-07-29T20:24:17.433
2015-07-29T13:29:06.643
5261
5261
question
c# unity3d
【C#】 Type型で指定した型に動的キャストするには


ジェネリックメソッドを動的に呼び出す場合のアプローチとしては

  * `Type`を引数にとる非ジェネリックな実装がないか探す。
  * `MethodInfo.MakeGenericMethod`を使用する。

の2つが考えられます。問題のライブラリで非ジェネリックな実装は公開されていないようなので、直球の方法としては以下のような流れになります。

[code]

    // オーバーロードがあるためGetMethodsを使用して全メソッドを取得
    var methods = typeof(JsonMapper).GetMethods(BindingFlags.Static | BindingFlags.Public);
    
    // 対象ジェネリックメソッド定義の抽出
    var genMethod = methods.First(m => m.Name == "ToObject"
                                    && m.IsGenericMethodDefinition
                                    && m.GetParameters()[0].ParameterType == typeof(string));
    
    // ジェネリックメソッド定義に型引数を渡して構築する
    // TODO:実際の型を指定する
    var constructed = genMethod.MakeGenericMethod(typeof(Hoge));
    
    // メソッドを実行する
    // 第一引数:実行対象のインスタンス…staticメソッドのためnull
    // 第二引数:メソッドに渡す引数の配列(object[])
    constructed.Invoke(null, new[] { json });
    
[/code]

という流れになるかと思います。

またソースを確認すると`JsonMapper.ToString<T>(string)`の実装は

[code]

    JsonReader reader = new JsonReader (json);
    return (T) ReadValue (typeof (T), reader);
    
[/code]

となっています。この`ReadValue(Type,
JsonReader)`メソッドはオーバーロードが簡単に解決できるので直接呼び出せば、コードが多少スッキリします。

[code]

    var method = typeof(JsonMapper).GetMethod(
                                        "ReadValue",
                                        BindingFlags.Static | BindingFlags.NonPublic,
                                        null,
                                        new [] { typeof(Type), typeof(JsonReader) },
                                        null);
    method.Invoke(null, new object[] {typeof(Hoge), new JsonReader(json)});
    
[/code]

さらに言えば、該当ライブラリはパブリックドメインのようですのでソースを改変して上記の`ReadValue`メソッドを呼び出せるようにするのが一番簡単な方法だと思います。


CC BY-SA 3.0
2015-07-29T11:06:54.533
12804
2015-07-29T20:24:17.433
2015-07-29T20:24:17.433
5750
5750
12801
answer