2009-04-15 6 views
1

Je prends une interface, je boucle sur le tableau de retour .GetEvents() et j'essaie d'implémenter l'événement sur mon type dynamique. Au moment où j'essaie d'appeler TypeBuilder.CreateType(), je suis accueilli avec cette belle erreur:Implémentation d'une interface sur un type dynamique avec des événements

"Méthode d'application sur le type de l'assembly est en train de remplacer une méthode qui a été substituée."

Si je commente le typeBuilder.DefineMethodOverride appelle cette tentative de mettre en œuvre les méthodes d'interface, au poin lorsque je tente de souscrire à l'événement, je reçois l'erreur:

« La méthode ou l'opération ne sont pas mises en œuvre. "

Voici la méthode que j'ai pour essayer d'ajouter l'événement détecté au type émis. Juste une note rapide, j'ai un autre code définissant le type et ajoutant des méthodes implémentant ceux sur l'interface et tout ce code fonctionne bien. Je n'ai eu aucun problème jusqu'à ce que j'essaye d'ajouter des événements dans le mélange.

protected static void AddEvent(EventInfo interfaceEvent, TypeBuilder proxyBuilder) 
    { 
     // Event methods attributes 
     MethodAttributes eventMethodAttr = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName; 
     MethodImplAttributes eventMethodImpAtr = MethodImplAttributes.Managed | MethodImplAttributes.Synchronized; 

     string qualifiedEventName = string.Format("{0}.{1}", typeof(T).Name, interfaceEvent.Name); 
     string addMethodName = string.Format("add_{0}", interfaceEvent.Name); 
     string remMethodName = string.Format("remove_{0}", interfaceEvent.Name); 

     FieldBuilder eFieldBuilder = proxyBuilder.DefineField(qualifiedEventName, 
      interfaceEvent.EventHandlerType, FieldAttributes.Public); 

     EventBuilder eBuilder = proxyBuilder.DefineEvent(qualifiedEventName, EventAttributes.None, interfaceEvent.EventHandlerType); 

     // ADD method 
     MethodBuilder addMethodBuilder = proxyBuilder.DefineMethod(addMethodName, 
      eventMethodAttr, null, new Type[] { interfaceEvent.EventHandlerType }); 

     addMethodBuilder.SetImplementationFlags(eventMethodImpAtr); 

     // We need the 'Combine' method from the Delegate type 
     MethodInfo combineInfo = typeof(Delegate).GetMethod("Combine", new Type[] { typeof(Delegate), typeof(Delegate) }); 

     // Code generation 
     ILGenerator ilgen = addMethodBuilder.GetILGenerator(); 
     ilgen.Emit(OpCodes.Ldarg_0); 
     ilgen.Emit(OpCodes.Ldarg_0); 
     ilgen.Emit(OpCodes.Ldfld, eFieldBuilder); 
     ilgen.Emit(OpCodes.Ldarg_1);      
     ilgen.Emit(OpCodes.Call, combineInfo);    
     ilgen.Emit(OpCodes.Castclass, interfaceEvent.EventHandlerType);  
     ilgen.Emit(OpCodes.Stfld, eFieldBuilder); 
     ilgen.Emit(OpCodes.Ret); 

     // REMOVE method 
     MethodBuilder removeMethodBuilder = proxyBuilder.DefineMethod(remMethodName, 
      eventMethodAttr, null, new Type[] { interfaceEvent.EventHandlerType }); 
     removeMethodBuilder.SetImplementationFlags(eventMethodImpAtr); 

     MethodInfo removeInfo = typeof(Delegate).GetMethod("Remove", new Type[] { typeof(Delegate), typeof(Delegate) }); 

     // Code generation 
     ilgen = removeMethodBuilder.GetILGenerator(); 
     ilgen.Emit(OpCodes.Ldarg_0); 
     ilgen.Emit(OpCodes.Ldarg_0); 
     ilgen.Emit(OpCodes.Ldfld, eFieldBuilder);  
     ilgen.Emit(OpCodes.Ldarg_1);     
     ilgen.Emit(OpCodes.Call, removeInfo);    
     ilgen.Emit(OpCodes.Castclass, interfaceEvent.EventHandlerType); 
     ilgen.Emit(OpCodes.Stfld, eFieldBuilder); 
     ilgen.Emit(OpCodes.Ret); 

     // Finally, setting the AddOn and RemoveOn methods for our event 
     eBuilder.SetAddOnMethod(addMethodBuilder); 
     eBuilder.SetRemoveOnMethod(removeMethodBuilder); 

     // Implement the method from the interface 
     proxyBuilder.DefineMethodOverride(addMethodBuilder, typeof(T).GetMethod("add_" + interfaceEvent.Name)); 

     // Implement the method from the interface 
     proxyBuilder.DefineMethodOverride(removeMethodBuilder, typeof(T).GetMethod("remove_" + interfaceEvent.Name)); 

    } 

Google a été 0 sur cette aide (recherche « est primordial une méthode qui a été réinitialisée » juste retourne beaucoup de Crystal Reports sujets), et je l'ai été aux prises avec ce toute la matinée. Toute aide serait considérablement apprécié!

Répondre

1

Nevermind. Lorsque je boucle la méthode de l'interface pour les implémenter, je mets en œuvre accidentellement l'ajout/suppression aussi. Je l'ai fixé dans ma boucle: if(method.IsSpecialName) continue;

Questions connexes