2016-11-17 10 views
1

渡された型のオブジェクトを返すコードを発行しました。ここでは、propertychange通知が仮想プロパティにラップされ、クライアントの変更追跡が行われます。この新しいタイプは、クライアントとサーバーの間で共有されます(protobuf.netを使用してシリアル化されます)。私はprotobuf.netの使用以外の第三者のライブラリを使用しないことに限定されています。IL Emit基本クラス名は継承クラスと同じです。 protobufferは循環継承を受け付けません

protobufferを使用して新しいオブジェクト(TypeAなど)のリストをシリアル化しようとすると、「予期しないサブタイプ:TypeA」が表示され、 SubTypeをRuntimeTypeModelを使ったprotobufferのモデルとして使用すると、私は "Cyclic inheritance is not allowed"を実行します。このprotobufferはこの時点でAFAIKを受け入れません。

私はReflection.Emitを初めて使用しました。少なくとも、名前が出ているタイプとは異なるタイプの新しいクラスをタイプする方法はありますか?この場合、私は循環的な継承制限を克服することができます。私は新しいオブジェクトの作成/コピーを避けたい。例えば

、として新しいオブジェクトを放出する:それは、シリアル化時にRuntimeTypeModelを使用したが判明

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見ていただきありがとうございます。私はコードのサンプルを添付しました。仮想のプロパティをpropertychangedでラップする擬似コードを提供した場所の詳細を知りたい場合は、教えてください。 – Option

+0

@ JeroenMostert私は完全に新しいタイプを発行し、Protobufferから同じエラーを受け取りました。これは、protobufferでリストのシリアライゼーションが行われる方法であるように見えます。リストのシリアライズ方法を調べる必要があります。もう一度見ていただきありがとうございます。私はできるだけ答えを掲示します。 – Option

答えて

2

NewTypeA 
-base TypeA 

代わりに:

TypeA 
-base TypeA 
-sub-type TypeA 

ILエミッタprotobufferを通して。送信された型を派生型でサブクラス化することには何も問題はありませんでした。

私の代わりにタイプAのインスタンスのタイプを追加するために必要な:

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

...私が持っていた前に:

もちろん、サイクリックエラーを返し、
RuntimeTypeModel.Default.Add(typeof(TypeA), true).AddSubType(555, TypeA); 

を。

これは将来的に誰かを助けてくれることを願っています。

関連する問題