public static MethodBuilder OverrideMethod(this TypeBuilder source, MethodBase parentMethod, Func<ILGenerator, ILGenerator> body, IDictionary<MethodBase, MethodBuilder> map) { // don't defer this check since default error message doesn't say // what exact method is the reason of the failure to compile the class parentMethod.IsVirtual.AssertTrue(); parentMethod.IsFinal.AssertFalse(); var attrs = parentMethod.Attributes; attrs &= ~MethodAttributes.NewSlot; attrs &= ~MethodAttributes.Abstract; var derived = source.DefineMethod( // that's an awesome idea but it hurts reflector and debuggability // String.Format("{0}_{1}", parentMethod.Name, parentMethod.DeclaringType.ToShortString()), parentMethod.Name, attrs, parentMethod.Ret(), parentMethod.Params()); parentMethod.GetParameters().ForEach((pi, i) => derived.DefineParameter(i + 1, ParmA.None, pi.Name)); // the stuff below ain't necessary at all since we don't change the name // // note. the checks are very important since otherwise we get an exception: // // System.TypeLoadException: Signature of the body and declaration in a method implementation do not match. // if (!parentMethod.IsAbstract && !parentMethod.IsGenericMethod) // { // source.DefineMethodOverride(derived, parentMethod); // } if (body != null) body(derived.il()); if (map != null) map[parentMethod] = derived; return derived; }
public static MethodBuilder DefineOverride(this TypeBuilder t, MethodBase @base) { MethodAttributes fixt = 0; var allAttrs = Enum.GetValues(typeof(MethodAttributes)).Cast<MethodAttributes>(); var validAttrs = allAttrs .Where(a => a != MethodAttributes.Abstract) .Where(a => a != MethodAttributes.NewSlot); validAttrs.ForEach(a => fixt |= (a & @base.Attributes)); (@base is MethodInfo).AssertTrue(); var @override = t.DefineMethod( @base.Name, fixt, @base.Ret(), @base.Params()); return @override; }