28

解決できない次の問題があります。

という名前のインターフェイスをすべて実装するさまざまなクラスがありますIProtocol。の名前は、今のところ 、SimpleProtocolですParallelProtocol。これらのオブジェクトを永続化したかったので、JSON.NET を使用し、すべて正常に動作しました。それらを逆シリアル化しようとしている場合を除き、それらが本来あるべき型を知っている場合は完全に機能します。たとえば、次のようになります。

SimpleProtocol p = JsonConvert.DeserializeObject<SimpleProtocol>(myJsonData);

しかし、私は今、JSON データを読み込んでデータを取得したい状況にありますIProtocolが、当然のことながら、JSON では許可されていません。たとえば、次のようなものは機能しませ

IProtocol p1 = JsonConvert.DeserializeObject<IProtocol>(myJsonData); // does not work
IProtocol p2 = (IProtocol)JsonConvert.DeserializeObject(myJsonData); // also, does not work

APIを調べてみると、次のメソッド シグネチャが見つかりました。

public static Object DeserializeObject(
    string value,
    Type type
)

これは私が必要としていたものとまったく同じように見えるので、型を文字列に永続化して取得することも試してみます。

// test
Type protocolType = Type.GetType("MyApp.Protocols.SimpleProtocol");
IProtocol p1 = JsonConvert.DeserializeObject(myJsonData, protocolType);

Newtonsoft.Json.Linq.JObjectaをにキャストできないというエラーが表示されIProtocolます。これは奇妙で、これを解決する方法がわかりません。

ジェネリック メソッドで Type オブジェクトを渡すことは不可能なので、基本的にここで立ち往生しています。できればリフレクションを使用せずに、これを解決する方法はありますか? これは完全に通常の使用例だと思います。

私にできることは、少し「汚い」ように思えますが、IProtocolインスタンスを保持する単純なラッパークラスを作成し、それをシリアル化/逆シリアル化することですか?

4

1 に答える 1

39

結局、この方法を使用した最初のアプローチは正しかったようです。

public static Object DeserializeObject(
    string value,
    Type type
)

問題は、オブジェクト タイプを using として永続化しMyProtocol.GetType().FullNameた結果、次の値が得られたことでした。

Type protocolType = Type.GetType(PersistedTypeString);

値を持つ Type になりnullます。ただし、MyProtocol.GetType().AssemblyQualifiedNameすべてを使用すると問題なく動作します(psこれはType.GetType()のドキュメントにも含まれています)

ここに私のコードサンプルがあります:

Type ProtocolType = Type.GetType(MetaData["ProtocolType"]);
var Protocol = JsonConvert.DeserializeObject(Data["Protocol"], 
                                             ProtocolType, 
                                             JsonProtocolPersister.DefaultSettings);
return (IProtocol)Protocol;
于 2013-03-04T08:39:03.233 に答える