diff --git a/src/TypeImplementer.cs b/src/TypeImplementer.cs index 5e6839f..73d4f82 100644 --- a/src/TypeImplementer.cs +++ b/src/TypeImplementer.cs @@ -3,6 +3,7 @@ // See COPYING for details using System; +using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Collections.Generic; @@ -108,7 +109,8 @@ static void Implement (TypeBuilder typeB, Type iface, string interfaceName) ILGenerator ilg = method_builder.GetILGenerator (); GenHookupMethod (ilg, declMethod, sendMethodCallMethod, interfaceName, declMethod.Name); - if (declMethod.IsSpecialName) + // Is Event Or Property + if (declMethod.IsEvent () || declMethod.IsProperty ()) builders[declMethod.Name] = method_builder; } @@ -258,7 +260,7 @@ public static void GenHookupMethod (ILGenerator ilg, MethodInfo declMethod, Meth ilg.Emit (OpCodes.Ldstr, @interface); //special case event add/remove methods - if (declMethod.IsSpecialName && (declMethod.Name.StartsWith ("add_") || declMethod.Name.StartsWith ("remove_"))) { + if (declMethod.IsEvent () && (declMethod.Name.StartsWith ("add_") || declMethod.Name.StartsWith ("remove_"))) { string[] parts = declMethod.Name.Split (new char[]{'_'}, 2); string ename = parts[1]; @@ -565,6 +567,51 @@ static void GenTypeOf (ILGenerator ilg, Type t) } } + internal static class MethodBaseExtensions { + + static IDictionary> events = new Dictionary>(); + static IDictionary> properties = new Dictionary>(); + + private static void InitialiseType (Type type) + { + lock (typeof(MethodBaseExtensions)) { + if (events.ContainsKey (type) && properties.ContainsKey (type)) + return; + + events [type] = new HashSet(); + properties [type] = new HashSet(); + + type.GetEvents ().Aggregate (events [type], (set, evt) => { + set.Add (evt.GetAddMethod ()); + set.Add (evt.GetRemoveMethod ()); + return set; + }); + type.GetProperties ().Aggregate (properties [type], (set, prop) => { + set.Add (prop.GetGetMethod ()); + set.Add (prop.GetSetMethod ()); + return set; + }); + + events [type].Remove (null); + properties [type].Remove (null); + } + } + + public static bool IsEvent (this MethodBase method) + { + InitialiseType (method.DeclaringType); + HashSet methods = events [method.DeclaringType]; + return methods.Contains (method); + } + + public static bool IsProperty (this MethodBase method) + { + InitialiseType (method.DeclaringType); + HashSet methods = properties [method.DeclaringType]; + return methods.Contains (method); + } + } + internal delegate void TypeWriter (MessageWriter writer, T value); internal delegate void MethodCaller (object instance, MessageReader rdr, Message msg, MessageWriter ret);