3

シリアル化するデータを含むクラスがあります。

[Serializable]
public class SomeData {
    public int NumericField;
    public string StringField;
}

便利な拡張メソッドがあります。

public static string ToJson<T> (this T value) {
    // yay no compile-time checks for [Serializable]?
    if (!typeof(T).IsSerializable)
        throw new SerializationException("Object lacks [Serializable] attribute");

    var serializer = new DataContractJsonSerializer(typeof(T));

    using (var stream = new MemoryStream()) {
        using (var writer = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8)) {
            serializer.WriteObject(writer, value);
        }

        return Encoding.UTF8.GetString(stream.ToArray());
    }
}

私は実際にはクラスSomeDataを実装したいISerializableのですが、それを追加すると、メソッドを追加する必要があると言われます。

error CS0535: 'SomeData' does not implement interface member
System.Runtime.Serialization.ISerializable.GetObjectData(
System.Runtime.Serialization.SerializationInfo, 
System.Runtime.Serialization.StreamingContext)'

問題は、現在実行していることを正確に実行するだけでなく、クラスに制限ToJson<T>してISerializable、回避可能な例外をスローするようなものを誤って渡さないようにすることです。このような:

public static string ToJson<T> (this T value) where T : ISerializable

インターフェイスGetObjectDataを追加しない場合に得られる正確な動作を複製する、簡潔な実装またはその他のトリックはありますか?ISerializable継承するクラスに含めることができるもの、または簡潔な(そして常にまったく同じ)ものが必要です。すべてのクラスに貼り付けるだけで、何[Serializable]が起こるかを正確に把握できます。一般的なもの。パフォーマンスは大きな問題ではありませんが、使用できるのは.NetFramework3.5のみです。

アップデート:

私は[DataContract]の代わりに完全に使用したいと思っています[Serializable]が、それを実行した場合、実装できる一般的な方法があるので、実装しなかった場合とISerializableまったく同じように動作しますか?(上記と同じqnで、どこにでも表示されます)[DataContract]ISerializableDataContractSerializable

4

3 に答える 3

6

まったく必要ありませんISerializableし、自分自身を投げる必要もありませんSerializationExceptionDataContractJsonSerializer型がシリアライズ可能でない場合、例外がスローされます。このシリアライザーを使用して型をシリアライズ可能にするには、実際にはいくつかのオプションがあります。

  • シリアライズ可能な属性
  • DataContract 属性
  • ISerializable インターフェイス
  • なし (パブリック型で機能し、すべてのパブリック フィールドとプロパティをシリアル化します)

シリアライザーにチェックを実行させると、それらすべてがサポートされます。

アップデート

コメントで議論した後、次の点を強調したいと思います。

(少なくとも C# 5.0 では) シリアライズ可能性をコンパイル時にチェックすることはできませんでした。オブジェクトをインターフェイスとしてマークしSerializableたり、インターフェイスを実装したりしても、シリアライザーISerializableがオブジェクト グラフでシリアル化できない型に遭遇し、実行時に例外をスローしないという保証はありません。

于 2012-04-22T07:46:25.093 に答える
0
  1. あなた自身がコメントしたように、空白のインターフェースを追加し、それを拡張メソッドの制約として配置します。複数のタイプのパラメーター制約の制約C#ジェネリック構文としてISerializableを追加することもできます

  2. もう1つのオプションは、ISerializableと必要なメソッドを実装する基本クラスを継承することです。

于 2012-04-22T06:19:43.290 に答える
0

この現象を回避するには、変換された Visual C# .NET クラスに ISerializable.GetObjectData メソッドを実装します。これを行うには、変換された Visual C# .NET クラスに次のコードを追加します。

void System.Runtime.Serialization.ISerializable.GetObjectData(
    System.Runtime.Serialization.SerializationInfo info,
    System.Runtime.Serialization.StreamingContext context)
{
    // Code as required
}
于 2014-07-30T15:38:56.110 に答える