6

私は protobuf-net (バージョン 2.0.0.621) を使用しており、T が自分のクラスであり (内容は関係ありません)、T にサロゲートが設定されている List 型のシリアル化に問題があります。

サロゲートは次のように設定されます。

ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(MyClass), false).SetSurrogate(typeof(MyClassSurrogate));

私のクラス:

public class MyClass
{
    public int Number { get; set; }
}

[ProtoContract]
MyClassSurrogate
{
    [ProtoMember(1)]
    public int Number { get; set; }
}

次に、タイプ MyClass インスタンスの汎用リストを作成し、項目を入力して、次のようにシリアル化します。

ProtoBuf.Serializer.Serialize(stream, list);

問題は逆シリアル化で発生します。暗黙的な演算子変換のサロゲートで「null」を取得し続けます。

static public implicit operator MyClassSurrogate(MyClass myClass)

'myClass' は null です。

サロゲートを削除して MyClass を proto 属性で装飾すると、すべて正常に動作します。

私が間違っていることを教えてもらえますか?

ありがとう。

4

2 に答える 2

7

暗黙的な演算子の変換に null チェックを追加すると、問題が解決するようです。

public static implicit operator MyClassSurrogate(MyClass myClass)
{
    return myClass != null ? new MyClassSurrogate { Number = myClass.Number } : null;
}

暗黙的な演算子は、逆シリアル化時に null 値を使用して最初に 1 回呼び出され、その結果は無視されているように見えます。

MyClassSurrogate の完全な実装:

[ProtoContract]
public class MyClassSurrogate
{
    [ProtoMember(1)]
    public int Number { get; set; }

    public static implicit operator MyClassSurrogate(MyClass myClass)
    {
        return 
            myClass != null 
            ? new MyClassSurrogate { Number = myClass.Number } 
            : null;
    }

    public static implicit operator MyClass(MyClassSurrogate myClass)
    {
        return new MyClass { Number = myClass.Number };
    }
}

完全なシリアライゼーション/デシリアライゼーションの例:

var model = ProtoBuf.Meta.RuntimeTypeModel.Default;
model.Add(typeof(MyClassSurrogate), true);
model.Add(typeof(MyClass), false).SetSurrogate(typeof(MyClassSurrogate));
var stream = new System.IO.MemoryStream();
var list = new List<MyClass>();
for (int x = 0; x < 10; x++) list.Add(new MyClass { Number = x });            
ProtoBuf.Serializer.Serialize(stream, list);
stream.Seek(0, SeekOrigin.Begin);
var xs = ProtoBuf.Serializer.Deserialize<List<MyClass>>(stream);
foreach (var x in xs) Debug.WriteLine(x.Number);
于 2013-02-10T09:59:58.547 に答える
2

値 null は、逆シリアル化中を含め、かなり頻繁に使用されます。null を null に変換するように変換演算子に指示するだけで、これを修正できるはずです。

if(value == null) return null;

考えてみれば、「両方とも参照型の場合、null を自動的に null に変換する」を安全に追加できる可能性があります。

于 2013-02-10T10:01:35.587 に答える