2012-01-23 4 views
1

C'est ainsi que mes classes sont modélisées. désolé, il est long:fichier proto pour héritage multiple

[Serializable] 
[DataContract] 
public class RequestSection 
{ 
    [DataMember(Order = 1)] 
    public List<BaseA> Allrequests; 

    public RequestSection() 
    { 
     Allrequests = new List<BaseA>(); 
    } 
} 
[Serializable] 
[DataContract] 
[ProtoInclude(2, typeof(BaseA<derResponse1>))] 
[ProtoInclude(3, typeof(BaseA<derResponse2>))] 
public abstract class BaseA 
{ 
    [DataMember(Order = 1)] 
    public int baseA = 10; 
} 

[Serializable] 
[DataContract] 
[ProtoInclude(2, typeof(der1))] 
[ProtoInclude(3, typeof(der2))] 
public abstract class BaseA<T> : BaseA where T : ResponseBaseA, new() 
{ 
    T _Response; 
    /// <summary> 
    /// 
    /// </summary> 
    [System.Runtime.Serialization.DataMember(Order = 1)] 
    public new T Response 
    { 
     get { return _Response; } 
     set { _Response = value; } 
    } 
} 

[Serializable] 
[DataContract] 
public class der1 : BaseA<derResponse1> 
{ 
    [DataMember(Order = 1)] 
    public int derive1 = 20; 
} 
[Serializable] 
[DataContract] 
public class der2 : BaseA<derResponse2> 
{ 
    [DataMember(Order = 1)] 
    public int derive2 = 30; 
} 

[Serializable] 
[DataContract] 
[ProtoInclude(2, typeof(derResponse1))] 
[ProtoInclude(3, typeof(derResponse2))] 
public abstract class ResponseBaseA 
{ 
    [DataMember(Order = 1)] 
    public int responseBaseA = 100; 
} 
[Serializable] 
[DataContract] 
public class derResponse1 : ResponseBaseA 
{ 
    [DataMember(Order = 1)] 
    public int derResp1 = 200; 
} 
[Serializable] 
[DataContract] 
public class derResponse2 : ResponseBaseA 
{ 
    [DataMember(Order = 1)] 
    public int derResp2 = 300; 
} 

}

la façon dont nous créons eux est ici

RequestSection section = new RequestSection(); 
der1 der1 = new der1(); 
der2 der2 = new der2(); 

section.Allrequests.Add(der1); 
section.Allrequests.Add(der2); 

Iam pas en mesure de sérialisation section à l'aide protobuf-net (à la fois v1 et v2 - disent-ils sous-type inconnu) donc im essayant le modèle d'exécution.

Voici le fichier proto que j'utilise.

message RequestSection{ 
    repeated BaseA requests=1; 
} 
message BaseA{ 
    optional int32 baseA=1; 
    optional BaseA1Generic BaseA1Generic =2; 
    optional BaseA2Generic BaseA2Generic =3; 
} 
message BaseA1Generic{ 
    optional ResponseBaseA baseResponse =1; 
    optional Der1 requestDer1 = 2; 
} 
message BaseA2Generic{ 
    optional ResponseBaseA baseResponse =1; 
    optional Der2 requestDer2 = 3; 
} 
message ResponseBaseA{ 
    optional int32 responseBaseA = 1; 
    optional derResponse1 derivedResponse1 =2; 
    optional derResponse2 derivedResponse2 =3; 
} 
message derResponse1{ 
    optional int32 derResponse1 = 1; 
} 
message derResponse2{ 
    optional int32 derResponse2 = 1; 
} 
message Der1{ 
    optional int32 d1=1; 
} 
message Der2{ 
    optional int32 d2=1; 
} 

Son pas désérialisation sur le côté Java et obtenir que ce

requests { 
    baseA: 10 
    1000: "\302>\002\b\024" 
} 
requests { 
    baseA: 10 
    1001: "\302>\002\b\036" 
} 

Je suis en train de faire mon fichier proto générique parce que je peux avoir une classe (der1/der2/ou plus à l'avenir) sous demandes de section.

Répondre

2

Le problème en ce moment est que votre modèle spécifie les deux der1 et der2pour les deuxBaseA<derResponse1> et BaseA<derResponse2>, ce qui signifie qu'il ya deux voies à der1/der2. En v2, nous pouvons éviter cela en spécifiant l'héritage explicitement par type générique fermé; donc: retirer les deux [ProtoInclude(...)] de BaseA<T>, et utilisez plutôt:

RuntimeTypeModel.Default[typeof(BaseA<derResponse1>)].AddSubType(2,typeof(der1)); 
RuntimeTypeModel.Default[typeof(BaseA<derResponse2>)].AddSubType(3,typeof(der2)); 

Comme une note latérale; il n'est pas nécessaire qu'ils utilisent des nombres différents ici, puisqu'ils sont indépendants. Ils pourraient à la fois utiliser le champ 2 est vous aimez; mais utiliser des numéros de champs différents est bien aussi.