3

C# では、列挙型に任意の整数値を割り当てることができます。

値が範囲外の列挙型フィールドを持つオブジェクトを (protobuf-net 経由で) シリアル化しようとすると、例外がスローされます: ワイヤー値が列挙型 PersonLevel にマップされていません。

私の enum PersonLevel には Flags 属性がありません。

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public enum PersonLevel
{
  Unknown = 1
}

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public class Person
{
  ...

  public PersonLevel PersonLevel { get; set; }

  ...
}
var ms = new MemoryStream();

var person = new Person
{
  ...
  PersonLevel = (PersonLevel) 500
  ...
};

Serializer.Serialize(ms, person); //No wire-value is mapped to the enum PersonLevel

ビジネスオブジェクト(おそらくprotobuf属性)を変更せずにそれを行う機能はありますか?

4

2 に答える 2

6

ルールを単純化するために、いくつかの方法があります。Ravadre が指摘しているように、[Flags]検証は自動的に無効EnumPassthruになります。シリアル化/逆シリアル化を開始するであれば、これを手動で行うこともできます。

RuntimeTypeModel.Default[typeof(PersonLevel)].EnumPassthru = true;

説明があります:

/// <summary>
/// Gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather
/// than enforcing .proto enum rules. This is useful *in particular* for [Flags] enums.
/// </summary>
于 2013-03-01T12:00:15.680 に答える
2

できることは、intフィールドを作成して protobuf メッセージにパックし、プロパティを公開することです。これにより、intフィールドenumが自分のタイプ (ラッパー) として公開されます。

おそらくprotobufは整数とプロパティの両方をシリアル化しようとするため、暗黙的なフィールドを使用している場合、これはより困難になる可能性がありますenum。プロパティを明示的に試すことができ[ProtoIgnore]ますenum

ただし、列挙型が属性でマークされている場合、protobuf はこれを自動的に行うため[Flags]、列挙型を次のように変更します。

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
[Flags]
public enum PersonLevel
{
    Unknown = 1
}

動作させる必要があります。少なくともバージョン 2 では。

于 2013-03-01T10:33:18.857 に答える