{"id":3108,"date":"2010-07-19T17:30:00","date_gmt":"2010-07-19T17:30:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/implementing-method-override-covariance-on-c-part-3\/"},"modified":"2016-07-28T10:50:05","modified_gmt":"2016-07-28T10:50:05","slug":"implementing-method-override-covariance-on-c-part-3","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/implementing-method-override-covariance-on-c-part-3\/","title":{"rendered":"Implementing method override covariance on C# (Part 3)"},"content":{"rendered":"<p>To recap from my <a href=\"https:\/\/www.simple-talk.com\/community\/blogs\/simonc\/archive\/2010\/07\/14\/93495.aspx\">previous post<\/a>, we&#8217;re trying to create a class that has the same behaviour as an explicit interface implementation, in which we can change the return type to a more specific type, but for class overrides instead of interface implementations.<\/p>\n<p><b>(Ab)using explicit overrides<\/b><\/p>\n<p>To implement explicit interface implementations on the CLR, the C# compiler uses the <code>.override<\/code> directive I discussed in my previous post. For example, in the following code: <\/p>\n<pre>public interface IA {\n    object Method();\n}\n\npublic class B : IA {\n    public string Method() {\n         \/* ... *\/\n    }\n    \n    object IA.Method() {\n        return Method();\n    }\n}<\/pre>\n<p> the C# compiler turns the <code>IA.Method<\/code> explicit implementation into the following IL method declaration (don&#8217;t be put off by the dots in the method name; they are simply a rename to prevent name clashes within the containing class): <\/p>\n<pre>method private hidebysig newslot virtual final\n  instance object IA.Method() cil managed {\n    .override IA::Method\n    \n    ldarg.0\n    call instance string B::Method()\n    ret\n}<\/pre>\n<p>Although not allowed in C#, IL allows us to do the same thing with class overrides. With a <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/blogbits\/simon.cooper\/ExplicitOverrideHack.txt\">small example<\/a>, we can see that this accomplishes what we want: <\/p>\n<pre>Calling A.Method on A: System.Object\nCalling B.Method on B: System.String\nCalling A.Method on B: System.String<\/pre>\n<p> When <code>A.Method()<\/code> is called from C#, the compile-time result is an <code>object<\/code>, and when <code>B.Method()<\/code> is called, the compile-time result is a <code>string<\/code>. Mission accomplished.  <\/p>\n<p><b>What about class hierarchies?<\/b><\/p>\n<p>However, there is a problem with this. This works for the simple case of <code>B<\/code> overriding <code>A<\/code>, but what if we add in a third class <code>C<\/code> that inherits off <code>B<\/code>?<\/p>\n<p>The <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/blogbits\/simon.cooper\/ExplicitOverrideHackFail.txt\">IL code<\/a> for this example approximates to the following C# code: <\/p>\n<pre>public class A {\n    public object Method() {\n        return new object();\n    }\n}\n\npublic class B : A {\n    \/\/ String and Int32 both implement IComparable\n    public IComparable Method() {\n         return 1;\n    }    \n    \/\/ explicit override of A.Method()\n    override object A.Method() {\n        return Method();\n    }\n}\n\npublic class C : B {\n    public string Method() {\n        return String.Empty;\n    }\n    \/\/ further explicit override of A.Method\n    override object A.Method() {\n        return Method();\n    }\n}<\/pre>\n<p>Running this, we can see that this approach doesn&#8217;t work (<code>B.Method<\/code> returns an <code>Int32<\/code> as an <code>IComparable<\/code>): <\/p>\n<pre>Calling A.Method on A: System.Object\nCalling B.Method on B: System.Int32\nCalling C.Method on C: System.String\nCalling A.Method on B: System.Int32\nCalling A.Method on C: System.String\nCalling B.Method on C: System.Int32<\/pre>\n<p>Here, the virtual dispatch isn&#8217;t working when calling <code>B.Method<\/code> on an instance of <code>C<\/code>. This is because the virtual dispatch only works when calling <code>A.Method<\/code>, as that is the only method that is overridden. Well, we can fix this by moving the actual method implementation into the explicit override, so that all the variance methods call <code>A.Method<\/code> and hence invoke the virtual dispatch mechanism, although this does lose us some verification safety by using an explicit cast. The <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/blogbits\/simon.cooper\/ExplicitOverrideHackSwitch.txt\">IL code<\/a> approximates to the following C# code: <\/p>\n<pre>public class A {\n    public object Method() {\n        return new object();\n    }\n}\n\npublic class B : A {\n    \/\/ String and Int32 both implement IComparable\n    public IComparable Method() {\n        return (IComparable)((A)this).Method();\n    }    \n    override object A.Method() {\n        return 1;\n    }\n}\n\npublic class C : B {\n    public string Method() {\n        return (string)((A)this).Method();\n    }\n    \n    override object A.Method() {\n        return String.Empty;\n    }\n}<\/pre>\n<p>And this works as expected: <\/p>\n<pre>Calling A.Method on A: System.Object\nCalling B.Method on B: System.Int32\nCalling C.Method on C: System.String\nCalling A.Method on B: System.Int32\nCalling A.Method on C: System.String\nCalling B.Method on C: System.String<\/pre>\n<p>If an assembly containing this code is referenced &amp; used from C#, we will get the behaviour that we set out to achieve &#8211; calls to <code>A.Method()<\/code> return an <code>object<\/code>, <code>B.Method()<\/code> returns an <code>IComparable<\/code>, and <code>C.Method()<\/code> returns a <code>string<\/code>, with virtual dispatch calling the correct method according to the run-time type of the instance.<\/p>\n<p><b>Applying this to existing assemblies<\/b><\/p>\n<p>To apply this to existing assemblies as a proof-of-concept, I&#8217;ve written a <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/blogbits\/simon.cooper\/VarianceTransformation.cs.txt\">small program<\/a> using <a href=\"http:\/\/www.mono-project.com\/Cecil\">Mono Cecil<\/a> to apply this transformation to any method in an assembly with an <code>OverrideVarianceAttribute<\/code> applied to the return type. To return to the factory example in my <a href=\"https:\/\/www.simple-talk.com\/community\/blogs\/simonc\/archive\/2010\/07\/14\/93495.aspx\">first post<\/a>, it turns this: <\/p>\n<pre>class Foo1 {}\nclass Foo2 extends Foo1 {}\n\nclass Foo1Factory {\n    public virtual Foo1 GetFoo() { \/* ... *\/ }\n}\n\nclass Foo2Factory extends Foo1Factory {\n    [return: OverrideVariance(typeof(Foo2))]\n    public override Foo1 GetFoo() { \/* ... *\/ }\n}<\/pre>\n<p> into this: <\/p>\n<pre>class Foo1Factory {\n    public virtual Foo1 GetFoo() { \/* ... *\/ }\n}\n\nclass Foo2Factory extends Foo1Factory {\n    public Foo2 GetFoo() {\n        return (Foo2)((Foo1Factory)this).GetFoo();\n    }\n    override Foo1 Foo1Factory.GetFoo() { \/* ... *\/ }\n}<\/pre>\n<p>Although the CLR does not support true override variance, we&#8217;ve managed to create a transformation that produces the same behaviour, both for compile-type type checking and run-time virtual dispatch. Mission accomplished!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To recap from my previous post, we&#8217;re trying to create a class that has the same behaviour as an explicit interface implementation, in which we can change the return type to a more specific type, but for class overrides instead of interface implementations. (Ab)using explicit overrides To implement explicit interface implementations on the CLR, the&#8230;&hellip;<\/p>\n","protected":false},"author":186659,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[],"class_list":["post-3108","post","type-post","status-publish","format-standard","hentry","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3108","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/186659"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=3108"}],"version-history":[{"count":2,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3108\/revisions"}],"predecessor-version":[{"id":41919,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3108\/revisions\/41919"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=3108"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=3108"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=3108"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=3108"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}