2016-11-17 129 views
1

我已发射的代码,返回传递的类型,其中的propertyChange通知包裹成虚拟属性,与所述客户端修改跟踪的对象。这种新类型将在客户端和服务器之间共享(使用protobuf.net序列化)。除了使用protobuf.net之外,我仅限于不使用第三方库。IL Emit基类名称与继承类相同; protobuffer不接受环状继承

我遇到的问题是,当我尝试使用protobuffer序列化新对象列表(例如,TypeA)时,我遇到了“Unexpected sub-type:TypeA”,并且当我尝试添加SubType作为使用RuntimeTypeModel的原型缓冲区的模型,我遇到了“循环继承是不允许的”,这个原型缓冲区此时不接受AFAIK。

我是新来Reflection.Emit的 - 有输入发出比我发光,至少在名称类型不同的新类的方法吗?在这种情况下,我可能能够克服循环继承限制。我想避免创建/复制新对象。

例如,发出一个新的对象为:

NewTypeA 
-base TypeA 

代替:

TypeA 
-base TypeA 
-sub-type TypeA 

IL辐射源:

usage: Type aType = CreateProxy(TypeA); 
     Activator.CreateInstance(aType); 

public static Type CreateProxy(Type type) 
{ 
    var assmName = new AssemblyName("DynamicProxyAssembly"); 
    ab = AppDomain.CurrentDomain.DefineDynamicAssembly(assmName, AssemblyBuilderAccess.Run); 
    mb = _ab.DefineDynamicModule(assmName.Name); 

    TypeBuilder typeBuilder = mb.DefineType(type.Namespace + "." + type.Name + "__proxy", TypeAttributes.Public, type); 
    typeBuilder.AddInterfaceImplementation(typeof(INotifyPropertyChanged)); 

    FieldBuilder eventField = CreatePropertyChangedEvent(typeBuilder); 

    MethodBuilder raisePropertyChanged = CreateRaisePropertyChanged(typeBuilder, eventField); 

    MethodInfo isModifiedSetMethod = type.GetProperty("Modified").SetMethod; 

    foreach property in type where virtual, wrap method with propertychangednotification... 

    Type ret = typeBuilder.CreateType(); // this returns TypeA__proxy derived from itself (base=TypeA__proxy). 
} 
+1

一些代码将有相当大的帮助。完全不清楚你的意思是“排放与你排放的不同”。如果这就是你的意思,派生类总是可以退回到它们的基类。 –

+0

@JeroenMostert非常感谢您的采访。我附上了一个代码示例 - 请让我知道,如果您想了解更多细节,我提供了伪代码以包装属性已更改和修改的虚拟属性。 – Option

+0

@JeroenMostert我完全发射了一个新类型,并从Protobuffer接收到相同的错误。它看起来就像列表序列化在protobuffer中完成的方式,我需要查看列表序列化的方式。再次感谢您的关注。我会尽我所能发布答案。 – Option

回答

2

原来这是RuntimeTypeModel序列化时所使用通过protobuffer。使用派生类型对发射类型进行子分类没有任何问题。

我需要添加实例的类型,而不是类型A的:

RuntimeTypeModel.Default.Add(typeof(TypeA), true).AddSubType(555, typeAinstance.GetType()); 

...我收到:

RuntimeTypeModel.Default.Add(typeof(TypeA), true).AddSubType(555, TypeA); 

其中,当然,返回周期误差。

我希望这可以帮助别人的未来。