C# 属于<;T>;在运行时ProtoBuf网络模型中允许吗?

C# 属于<;T>;在运行时ProtoBuf网络模型中允许吗?,c#,.net,protobuf-net,C#,.net,Protobuf Net,我正在使用ProtoBuf net的第2版,目前我遇到错误“无法确定成员:A” 当我们使用ClassOfType时,是否可以为Protobuf net创建运行时模型?如果是这样的话,有人能发现我在下面的代码中遗漏了什么吗 顺便说一句:这个请求是模仿的,我可以得到一个版本的这个很好。。。但它们使用的是抽象基类,而不是T的泛型类 这是一个有效的例子(不起作用的东西被移除) 讨论: 当我在上面的链接中看到反序列化为抽象基类型的方法时,我想,是的,这更接近我们的想法。我们是否可以先反序列化到开放的泛型容

我正在使用ProtoBuf net的第2版,目前我遇到错误“无法确定成员:A”

当我们使用ClassOfType时,是否可以为Protobuf net创建运行时模型?如果是这样的话,有人能发现我在下面的代码中遗漏了什么吗

顺便说一句:这个请求是模仿的,我可以得到一个版本的这个很好。。。但它们使用的是抽象基类,而不是T的泛型类

这是一个有效的例子(不起作用的东西被移除)

讨论:

当我在上面的链接中看到反序列化为抽象基类型的方法时,我想,是的,这更接近我们的想法。我们是否可以先反序列化到开放的泛型容器,然后在需要在不同的程序集中进行更具体的强制转换。也许我有点搞混了

你可以用tuple来考虑它。或者像Tupple这样的变体。列出来也没什么不同。我也有一些Treetypething,但我不需要(现在)序列化/反序列化它们

我有一个非通用序列工作,所以它不是一个显示停止。我的第一个实现可能更高效。不过,我认为我可以在现有protobuf网络功能的基础上做得更好

我喜欢用更简洁的方法来处理这些想法。虽然我可以手动到达相同的目的地,但泛型使其他事情成为可能

回复:澄清

调用方可以提前定义所有内容。(顺便说一句:你现在让我考虑只运行时的场景,但不,我不需要这个)。

所以我认为问题可以归结为“我可以使用开放泛型类型作为protobuf模型的模板吗”,在这种情况下,答案是“可能”。目前,它会将
BasicMsg
BasicMsg
视为不同的类型,并默认使用属性类型模型,因为它不会识别它们是由
[typeof(BasicMsg)]
定义的。如果他们有属性,这可能会起作用,但我不认为这是你的意图,对吗

这是一个有趣的场景,我愿意就此展开讨论。然而,这里我要特别关注的是.NET中泛型的性质意味着这需要运行时参与,即
RuntimeTypeModel
。我认为如果不使用
MakeGenericMethod
,我就无法在预编译的
TypeModel
上运行它,因为平台和性能的原因,我确实希望避免使用
MakeGenericMethod
。但作为一个完整的.NET运行时功能,它看起来很有趣


(对以上内容的澄清;如果调用方能够提前定义
BasicMsg
的所有
T
,那么它就变得更可行了;然后它实际上归结为一个模型模板隐喻)

感谢您的关注。非常好。上面的注释,而不是试图将它们放入tweetx3中。是否可以用基元类型序列化对象?我在模型中尝试了很多组合。顺便说一句:你想把这个请求作为一个新问题吗?@sgtz你能更具体一点吗?新问题发布在@sgtz上如果它是关于这个问题的主题,只需编辑它并让我知道“无法确定成员:a”-这仅仅是因为没有名为
a
,顺便说一句的成员。同样
B
C
D
E
@Marc Gravell我来看看。我认为。添加(1,“A”)也创建了标签。它走不了那么远。有道理。哦。@Marc Gravell:最后我一切都正常了+修改了上面的示例代码以反映这一点。再次感谢。让我们把开放泛型留到下次再看吧。
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>>(...):
  public MetaType Add(int fieldNumber, string memberName, Type itemType, Type defaultType);