16

I currently have an extension method on System.Windows.Forms.Control like this:

public static void ExampleMethod(this Control ctrl){ /* ... */ }

However, this method doesn't appear on classes derived from Control, such as PictureBox. Can I make an extension method that appears not only in Control, but for classes derived from Control, without having to do an explicit cast?

Jason
  • 28,040
  • 10
  • 64
  • 64
MiffTheFox
  • 21,302
  • 14
  • 69
  • 94
  • Possible duplicate of [Why can't I call an extension method from a base class of the extended type‏?](http://stackoverflow.com/questions/27883427/why-cant-i-call-an-extension-method-from-a-base-class-of-the-extended-type) – Mauro Palumbo Nov 29 '16 at 11:31

5 Answers5

19

You must include the using statement for the namespace in which your extensions class is defined or the extension methods will not be in scope.

Extension methods work fine on derived types (e.g. the extension methods defined on IEnumerable<T> in System.Linq).

ShuggyCoUk
  • 36,004
  • 6
  • 77
  • 101
8

An extension method will actually apply to all inheritors/implementors of the type that's being extended (in this case, Control). You might try checking your using statements to ensure the namespace that the extension method is in is being referenced where you're trying to call it.

Nate Kohari
  • 2,216
  • 17
  • 13
7

Note that if you call an extension method from a property in class which inherits from a base class that has the extension method applied to it, you have to suffix the extension method with this

e.g.

public int Value
{
    get => this.GetValue<int>(ValueProperty);
    set => SetValue(ValueProperty, value);
}

Where GetValue is my extension method applied to the base class.

Jon Barker
  • 1,788
  • 15
  • 25
  • 1
    I had the same problem inside a method. Your solution worked, thanks! – Xymanek Aug 20 '18 at 17:43
  • 1
    This bit me and was something I never knew - thanks! Note that (at least in VS2022), Intellisense _sometimes_ won't suggest the extension method even after typing `this.`, which was why I couldn't figure this out myself. (I suspect it happens when the derived class is in a different module.) – Bob Sammers Oct 31 '22 at 10:43
2

You can also make sure your extensions aren't defined in a namespace, then any project that references them will auto-import them.

Maslow
  • 18,464
  • 20
  • 106
  • 193
1

I think you have to make the extension generic:

public static void ExampleMethod<T>(this T ctrl)
    where T : Control 
{ /* ... */ }

No, you don't have to.. it should also work with the non-generic version you posted, remember to add the namespace for your extensions.

Paul van Brenk
  • 7,450
  • 2
  • 33
  • 38
  • Top !! It works like a charm ! This is the only method that works when you have to return type T ! Thanks ! (public static T ExampleMethod...) – A. Morel Apr 17 '20 at 10:16