I cannot figure out how to use MethodImpl's to override a virtual method when I have multiple levels of inheritance using MethodImpl's. Let's start with a simple C# example:
internal class Base { public override string ToString () { return "Base"; } } internal class Derived : Base { public override string ToString () { return "Derived"; } } internal class MoreDerived : Derived { public override string ToString () { return "MoreDerived"; } } internal class App { static void Main () { MoreDerived m = new MoreDerived (); Derived d = m; Base b = m; object o = m; System.Console.WriteLine ("Object.ToString() returns " + o.ToString()); System.Console.WriteLine ("Base.ToString() returns " + b.ToString()); System.Console.WriteLine ("Derived.ToString() returns " + d.ToString()); System.Console.WriteLine ("MoreDerived.ToString() returns " + m.ToString()); } } Given the above class hierarchy, running the program produces the following expected output: Object.ToString() returns MoreDerived Base.ToString() returns MoreDerived Derived.ToString() returns MoreDerived MoreDerived.ToString() returns MoreDerived Now, let's rename the Base.ToString method to Base.Foo but still have it override System.Object.ToString. A quick ILDASM, a change to the Base class and reassemble: .class private auto ansi beforefieldinit Base extends [mscorlib]System.Object { .method public hidebysig virtual instance string Foo() cil managed { <snip> } // end of method Base::ToString .override [mscorlib]System.Object::ToString with instance string Base::Foo() <snip> } // end of class Base I run the modified program and get the same, expected output: Object.ToString() returns MoreDerived Base.ToString() returns MoreDerived Derived.ToString() returns MoreDerived MoreDerived.ToString() returns MoreDerived Now, the problem I cannot seem to solve: I now want to modify the Derived class so that it has a method called 'Bar' that overrides Base.ToString. Of course, Base.ToString doesn't really exist, but Base.Foo exists and it's its implementation I really want to override. So I change the definition of Derived like so: .class private auto ansi beforefieldinit Derived extends Base { .method public hidebysig virtual instance string Bar() cil managed { <snip> } // end of method Derived::ToString .override Base::Foo with instance string Derived::Bar() <snip> } // end of class Derived Now the program won't load due to a TypeLoadException: Unhandled Exception: System.TypeLoadException: Method Foo on type Derived from assembly Foo is overriding a method impl. at App.Main() (Yes, the error message itself is a little wrong but that's an unrelated problem.) So I figure conceptually I want to override Base.ToString so I changed the .override to: .override Base::ToString with instance string Derived::Bar() But I still get the same exception: Unhandled Exception: System.TypeLoadException: Method Foo on type Derived from assembly Foo is overriding a method impl. at App.Main() So finally, I changed the .override to: .override [mscorlib]System.Object::ToString with instance string Derived::Bar() Now the program loads and runs but the output isn't what I expected or want: Object.ToString() returns MoreDerived Base.ToString() returns Base Derived.ToString() returns MoreDerived MoreDerived.ToString() returns MoreDerived Basically, the question becomes how can I make Derived::Bar use the same vtbl slot as Base::Foo which itself is using the same vtbl slot as System.Object::ToString? -- Brent Rector, .NET Wise Owl Demeanor for .NET - an obfuscation utility http://www.wiseowl.com/Products/Products.aspx You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.