我使用的版本2 protobuf網的,目前我在歌廳錯誤「無法確定會員:A」是否允許在運行時ProtoBuf-net模型中使用<T>?
是否有可能當我們用ClassOfType創建protobuf網運行時模式< T>?如果是這樣,任何人都可以發現我在下面的代碼中缺少的東西嗎?
BTW:這個請求被建模斷Deserialize unknown type with protobuf-net我能得到一個版本這是怎麼回事就好了...但他們使用的是一個抽象基類,而不是一個泛型類T.
的這是施工示例(不工作的東西被刪除)。
using System;
using System.IO;
using NUnit.Framework;
using ProtoBuf;
using ProtoBuf.Meta;
namespace ProtoBufTestA2
{
[TestFixture]
public class Tester
{
[Test]
public void TestMsgBaseCreateModel()
{
var BM_SD = new Container<SomeDerived>();
using (var o = BM_SD) {
o.prop1 = 42;
o.payload = new SomeDerived();
using (var d = o.payload) {
d.SomeBaseProp = -42;
d.SomeDerivedProp = 62;
}
}
var BM_SB = new Container<SomeBase>();
using (var o = BM_SB) {
o.prop1 = 42;
o.payload = new SomeBase();
using (var d = o.payload) {
d.SomeBaseProp = 84;
}
}
var model = TypeModel.Create();
model.Add(typeof(Container<SomeDerived>), true); // BM_SD
model.Add(typeof(Container<SomeBase>), true); // BM_SB
model.Add(typeof(SomeBase), true); // SB
model.Add(typeof(SomeDerived), true); // SD
model[typeof(SomeBase)].AddSubType(50, typeof(SomeDerived)); // SD
var ms = new MemoryStream();
model.SerializeWithLengthPrefix(ms, BM_SD, BM_SD.GetType(), ProtoBuf.PrefixStyle.Base128, 0);
model.SerializeWithLengthPrefix(ms, BM_SB, BM_SB.GetType(), ProtoBuf.PrefixStyle.Base128, 0);
ms.Position = 0;
var o1 = (Container<SomeDerived>)model.DeserializeWithLengthPrefix(
ms
, null
, typeof(Container<SomeDerived>), PrefixStyle.Base128, 0);
var o2 = (Container<SomeBase>)model.DeserializeWithLengthPrefix(
ms
, null
, typeof(Container<SomeBase>), PrefixStyle.Base128, 0);
}
}
[ProtoContract]
public class Container<T> : IDisposable
{
[ProtoMember(1)]
public int prop1 { get; set; }
[ProtoMember(2)]
public T payload { get; set; }
public void Dispose() { }
}
[ProtoContract]
public class AnotherDerived : SomeDerived, IDisposable
{
[ProtoMember(1)]
public int AnotherDerivedProp { get; set; }
public override void Dispose() { }
}
[ProtoContract]
public class SomeDerived : SomeBase, IDisposable
{
[ProtoMember(1)]
public int SomeDerivedProp { get; set; }
public override void Dispose() { }
}
[ProtoContract]
public class SomeBase : IDisposable
{
[ProtoMember(1)]
public int SomeBaseProp { get; set; }
public virtual void Dispose() { }
}
[ProtoContract]
public class NotInvolved : IDisposable
{
[ProtoMember(1)]
public int NotInvolvedProp { get; set; }
public void Dispose() { }
}
[ProtoContract]
public class AlsoNotInvolved : IDisposable
{
[ProtoMember(1)]
public int AlsoNotInvolvedProp { get; set; }
public void Dispose() { }
}
}
請求
這是次要的,但它會是如果
(Container<SomeDerived>)model.DeserializeWithLengthPrefix(...)
也可以實現這樣的
model.DeserializeWithLengthPrefix<Container<SomeDerived>>(...):
BTW不錯:我開始深入protobuf網實施,我開始注意到一些像這樣的teresting方法。東西回來後,我想:
public MetaType Add(int fieldNumber, string memberName, Type itemType, Type defaultType);
討論:
當我看見你可以反序列化在上面的鏈接的抽象基類的方式,我想,是的,這是接近在想什麼。我們是否可以首先反序列化到開放的通用容器<>,然後如果我們需要在不同的程序集中進行更具體的轉換。也許我在這裏混了一點。
你可以根據Tupple < TBase,TPayload>來考慮它。或者像Tupple < TBase,懶惰< TPayload >>也許。這與列表< T>沒有什麼不同。我也有一些TreeTypeThings,但我不需要序列化/反序列化它們(還)。
我有一個非通用的序列工作,所以它不是一個顯示塞。我的第一個實施可能會更有效率。儘管如此,我認爲我可以在現有的protobuf-net功能上做得更好。
我喜歡使用這些想法的更清潔的通用方法。儘管我可以手動到達相同的目的地,但泛型使其他事情成爲可能。
重:澄清
一切都可以被調用者提前定義。 (順便說一句:你讓我現在想着僅限於運行時的場景,但不,我不需要)。
重新「無法確定成員:A「 - 這只是因爲*沒有名爲'A' *的成員,順便說一句。同樣地'B','C','D'或'E'。 –
@Marc Gravell我會看看。我認爲* .Add(1,「A」)也創建了標籤。它不能那麼遠。說得通。哎呀。 – sgtz
@Marc Gravell:我最終得到了一切正常工作+改變了上面的示例代碼來反映這一點。再次感謝。讓我們把開放的泛型看作是另一回事。 – sgtz