Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to "override" extension methods in .NET?
    primarykey
    data
    text
    <p>So I have an object hierarchy to produce ui controls in asp.net mvc and try to achive a fluent api. I make some dummy class to focus on the current problem.<br> So here is the "wrong" codebase:</p> <pre><code>public abstract class HtmlElement { /* ... */ } public abstract class UIElement : HtmlElement { /* ... */ } public abstract class ButtonBase : UIElement { /* ... */ } public class LinkButton : ButtonBase { /* ... */ } public class ActionButton : ButtonBase { /* ... */ } public static class HtmlElementExtensions { public static T Id&lt;T&gt;(this T item, string id) where T : HtmlElement { /* set the id */ return item; } } public static class ButtonBaseExtensions { public static T Id&lt;T&gt;(this T item, string id) where T : ButtonBase { /* set the id and do some button specific stuff*/ return item; } } </code></pre> <p>When I try to call the Id on a LinkButton the compiler says there is ambiguous call: </p> <pre><code>LinkButton lb = new LinkButton().Id("asd"); </code></pre> <p>I really thought that the compiler choose the closest match in this case so if I have a Script class that inherits from HtmlElement than HtmlExtensions Id method called, and for a LinkButton (because of the restrictions) the ButtonBase method will be called. I have a solution, but I'm not sure there is a better one.<br> I delete the Id method from ButtonBaseExtensions and modified the HtmlElementExtensions Id method as the following manner:</p> <pre><code>public static T Id&lt;T&gt;(this T item, string id) where T : HtmlElement { if (item is ButtonBase) { /* do some button specific stuff*/ } /* set the id */ return item; } </code></pre> <p>This way every class descendant from the ButtonBase is working. I not really like my solution because it mix the HtmlElement logic with the ButtonBase logic. Any idea/suggestion for a better solution? I thought I put them in different namespace, but just for a second. I should have to use both namespace, so don't solve the problem. </p> <p>Do you think it's worth to mention on the msdn forums as an idea that the compiler should watch the restrictions on generic extension methods?</p> <p>In the meantime I make some more research and start a thread on msdn forums: <a href="http://social.msdn.microsoft.com/Forums/en-US/clr/thread/c9ad51c1-0c5a-4eb6-a530-89eaa628c07f" rel="nofollow">link</a><br> I tried some non-generic extension methodds: </p> <pre><code> public class BaseClass { /*...*/ } public class InheritedClass : BaseClass { /*...*/ } public static class BaseClassExtensions { public static void SomeMethod(this BaseClass item, string someParameter) { Console.WriteLine(string.Format("BaseClassExtensions.SomeMethod called wtih parameter: {0}", someParameter)); } } public static class InheritedClassExtensions { public static void SomeMethod(this InheritedClass item, string someParameter) { Console.WriteLine(string.Format("InheritedClassExtensions.SomeMethod called wtih parameter: {0}", someParameter)); } } </code></pre> <p>And if I instantiate these:</p> <pre><code>BaseClass bc = new BaseClass(); InheritedClass ic = new InheritedClass(); BaseClass ic_as_bc = new InheritedClass(); bc.SomeMethod("bc"); ic.SomeMethod("ic"); ic_as_bc.SomeMethod("ic_as_bc"); </code></pre> <p>Produced this output:</p> <pre><code>BaseClassExtensions.SomeMethod called wtih parameter: bc InheritedClassExtensions.SomeMethod called wtih parameter: ic BaseClassExtensions.SomeMethod called wtih parameter: ic_as_bc </code></pre> <p><a href="http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3886276-generic-extension-method-type-restriction-should-b" rel="nofollow">You can vote it for now</a></p> <p>Thanks,<br> Péter</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload