4

データを内部的に格納するコレクションのインターフェイスを作成しようとしています。JObject

internal class JsonDataSet : IDataSet
{
    private JObject Document { get; set; }

    // The following methods are from the IDataSet interface
    public int Count { ... }
    public void Add<T>(string key, T value) { ... }
    public T GetItem<T>(string key) { ... }
    public bool ContainsKey(string key) { ... }
}

メソッドでは、カスタム型に注釈Add<T>がない場合に便利な例外を提供したいと考えています。DataContractたとえば、誰かが次のように呼び出した場合:

dataSet.Add<IDictionary<string, IList<CustomType>>>(dict);

適切な注釈がない"Cannot serialize type 'CustomType'. DataContract annotations not found."場合、例外がスローされます。CustomType

これまでのところ、型定義ですべてのジェネリック引数を取得する方法を見つけたので、それらを確認できます。

private IEnumerable<Type> GetGenericArgumentsRecursively(Type type)
{
    if (!type.IsGenericType) yield return type;

    foreach (var genericArg in type.GetGenericArguments())
        foreach (var yieldType in GetGenericArgumentsRecursively(genericArg ))
            yield return yieldType;
}

そして、次のように add メソッドを実装しようとしました:

public void Add<T>(string key, T value)
{
    foreach(var type in GetGenericArgumentsRecursively(typeof(T)))
    {
        if(!type.IsPrimitive && !Attribute.IsDefined(type, typeof(DataContractAttribute)))
            throw new Exception("Cannot serialize type '{0}'. DataContract annotations not found.", typeof(T));
    }

    Document.Add(new JProperty(key, JToken.Parse(JsonConvert.SerializeObject(value))));
}

これは、プリミティブ型とカスタム型では機能すると思いますが、非ジェネリックな .NET 型にはすべてのDataContract注釈があるわけではないため、機能しません。によってシリアル化できる型を知る方法はありJsonConvertますか?

4

1 に答える 1

6

Json.NET は、カスタム属性を持たないものも含め、ほぼすべての型をサポートしています。サポートされている属性には、DataContract、JsonObject、Serializable があります。Json.NET にメンバーをシリアライゼーションに含めたり、スキップさせたりする方法は多数あります。一部のクラスをシリアル化できない場合は、Data* 属性の欠如以外の問題が原因である可能性が高くなります: 例外をスローするメンバー、コンストラクターの欠落、コンバーターの欠陥、可視性の問題など。 Json.NET。

事前にテストしたい場合は、Json.NET から膨大な量のロジックを複製する必要があります。型とメンバーの属性を確認するだけでは不十分です。プロパティに使用されるコンバーターを確認するだけでも、少なくとも 5 か所を確認する必要があります。新しいバージョンでは、Json.NET に新しい型、コンバーター、機能、または属性が導入され、これらすべてをもう一度行う必要があるためです。

型をシリアル化できるかどうかをテストする唯一の信頼できる方法は、シリアル化を試みることです。

于 2013-09-10T02:26:49.527 に答える