This is a deficiency in the current version of the Loader -- explicit overrides (through MethodImpls) cannot be chained. At the same time, implicit overrides can be chained alright, which creates an assymetry between explicit and implicit overrides.
Partition II says nothing about limitations on explicit override chaining, which implies there should be no such limitations. The only limitation specified in Partition II is that the same v-table slot can't be overridden with more than one method, and in the case Brent is citing this doesn't happen. Clearly, this deficiency needs fixing. And I extend our profound thanks to Brent, The Intrepid Vigilante of Partition II and Surrounding Territories! --Serge -----Original Message----- From: Brent E. Rector [mailto:[EMAIL PROTECTED]] Sent: Monday, May 20, 2002 2:25 PM To: [EMAIL PROTECTED] Subject: [DOTNET] Partition II Metadata Spec question 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. You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.
