2012-12-09 14 views
3

protobuf-net,你可以用ProtoEnumAttribute覆蓋爲枚舉線格式,像這樣:模仿ProtoEnumAttribute與ProtoBuf.Meta接口

[ProtoContract] 
enum MyEnum 
{ 
    [ProtoEnum(Value=1)] 
    Default, 
    [ProtoEnum(Value=10)] 
    Foo 
} 

有了這些屬性,其中Default通常會序列化到0Foo1他們現在將分別序列化爲110

我想要做的就是使用ProtoBuf.Meta中的接口模仿這種行爲,所以我不必註釋枚舉(因爲我通常不會在我的項目中控制它們)。

通過protobuf網的源挖掘,我已經成功地得到以下(簡化了一下)工作:(!只讀)

var model = RuntimeTypeModel.Create(); 
var meta = model.Add(enumType, applyDefaultBehaviour: true); 

var fields = meta.GetFields(); 

// Oh god why 
var fieldNumber = 
     typeof(ValueMember).GetField(
     "fieldNumber", 
     System.Reflection.BindingFlags.Instance | 
     System.Reflection.BindingFlags.NonPublic 
    ); 

List<string> ordered = GetDesiredEnumOrder(enumType); 
int equiv = 0; 
foreach (var val in ordered) 
{ 
    var field = fields.Single(f => f.Name == val); 
    fieldNumber.SetValue(field, equiv); 
    equiv++; 
} 

但是我不能船舶這個依靠反映爲一體的民營領域,這只是要求麻煩。

那麼,是否有支持的方式來覆蓋protobuf-net在運行時的枚舉線值?

回答

2

我不是在PC來檢查這一點,所以你必須糾正我,如果我在做瘋狂的談話,但它應該是這樣的(早在應用程序):

RuntimeTypeModel.Default.Add(typeof(MyEnum), false) 
    .Add(1, "Default").Add(10, "Foo"); 

第一行告訴它將新的Type添加到模型,沒有false)應用任何常用規則;第二行添加2個成員到該類型的表示,並具有所需的值。

如果這不起作用(我今天晚些時候會試着檢查),讓我知道,我會使它的工作(或提供一個等效的API)。這可能只是因爲這種情況根本沒有出現在我沒有屬性的情況下進行驗證。

+0

不,你得到「無法確定成員:默認」。看起來像Add/AddField只考慮實例成員。 –

+0

@Kevin k;將在24小時內修復並重新部署。直到現在我的手肘部分電腦(不是我的主電腦,幸運的是!) –

+0

@Kevin修補並推送;見2.0.0.612 –