C# 协议网络';s[ProtoInclude(1,“MyClass”)不起作用

C# 协议网络';s[ProtoInclude(1,“MyClass”)不起作用,c#,protobuf-net,C#,Protobuf Net,我正在使用protobuf net v2 beta r431作为C#.net 4.0应用程序。在我的应用程序中,我有一个需要序列化的字典。类MyClass实现IMyClass接口。根据protobuf的文档,我编写了如下代码: [ProtoContract] [ProtoInclude(1, typeof(MyClass))] public interface IMyClass { int GetId(); string GetName(); } [ProtoContract]

我正在使用protobuf net v2 beta r431作为C#.net 4.0应用程序。在我的应用程序中,我有一个需要序列化的
字典。类
MyClass
实现
IMyClass
接口。根据protobuf的文档,我编写了如下代码:

[ProtoContract]
[ProtoInclude(1, typeof(MyClass))]
public interface IMyClass
{
    int GetId();
    string GetName();
}

[ProtoContract]
[Serializable]
public class MyClass : IMyClass
{
    [ProtoMember(1)]
    private int m_id = 0;

    [ProtoMember(2)]
    private string m_name = string.Empty;

    public MyClass(int id, string name)
    {
        m_id = id;
        m_name = name;
    }

    public MyClass()
    {
    }

    #region IMyClass Members

    public int GetId()
    {
        return m_id;
    }

    public string GetName()
    {
        return m_name;
    }

    #endregion
}
但是,根据我的应用程序的设计,接口是在更高的级别上定义的(在不同于类的项目中),并且不可能在编译时确定实现此接口的类。因此,它给出了[ProtoInclude(1,typeof(MyClass))]的编译时错误。我尝试使用[ProtoInclude(int标记,string KownTypeName)],如下所示:

[ProtoContract]
[ProtoInclude(1, "MyClass")]
public interface IMyClass
{
    int GetId();
    string GetName();
}
但是,这在第行抛出了一个“对象引用未设置为对象实例”异常

Serializer.Serialize(stream, myDict);
其中Dictionary myDict=newdictionary(int,IMyClass)();
请让我知道在这种情况下如何使用ProtoInclude,以便在字典/列表中序列化接口类型。

因为它不知道从哪里获取您的
MyClass
,您可能应该使用您的类的值

下面是一些示例代码:

namespace Alpha
{
    [ProtoContract]
    [ProtoInclude(1, "Bravo.Implementation, BravoAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")]
    //[ProtoInclude(1, "Bravo.Implementation")] // this likely only works because they're in the same file
    public class PublicInterface
    {            
    }
}

namespace  Bravo
{
    public class Implementation : Alpha.PublicInterface
    {            
    }

    public class Tests
    {
        [Test]
        public void X()
        {
            // no real tests; just testing that it runs without exceptions

            Console.WriteLine(typeof(Implementation).AssemblyQualifiedName);

            using (var stream = new MemoryStream())
            {
                Serializer.Serialize(stream, new Implementation());
            }
        }
    }
}
Austin是正确的(我相信):使用程序集限定名(作为字符串)应该可以解决这个问题

在v2中,存在一个附加选项:您可以在运行时而不是通过属性执行映射:

RuntimeTypeModel.Default[typeof(PulicInterface)]
    .AddSubType(1, typeof(Implementation));

如果你的“应用”层知道这两种类型,可以通过静态代码实现,也可以通过一些自定义配置/反射过程实现。

也就是说,你应该等待Marc Gravell如何响应,因为这肯定是解决问题的方法。在v1中,这就是“方法”。在v2中,它是两种方式之一。一个很好的答案,虽然-节省了我很多打字。