9

I understand that C# extension methods must be static. What I don't understand is why these extensions can't be defined in non static classes or generic ones?

Update: I am interested in the reason behind this design decision.

Mehran
  • 1,977
  • 1
  • 18
  • 33
  • I search throughly for static class case before asking this question and I have not found the answer you refered to. By the way it's not exactly the same question and my answer is not found in that post. – Mehran Aug 23 '11 at 16:22
  • How is this an *exact* duplicate of "Why is it impossible to declare extension methods in a generic static class?". – Tim Lloyd Aug 23 '11 at 16:55
  • This isn't a duplicate. Rather a more specific question out of the so called double. – Arpit Khandelwal Aug 04 '14 at 12:11

3 Answers3

9

This is more of an observation than an answer, but...

When you call an instance method, a reference to the object you are calling is pushed onto the stack as the first argument in your method call. That first argument is "this" and is done implicitly.

When you define an extension method, you explicitly define a "this" as the first argument.

Is it possible that method resolution would be confusing if you could define extension methods and instance methods in the same class i.e. defining methods with the same name and, in effect, the same parameters when the "this" parameter is included.

Tim Lloyd
  • 37,954
  • 10
  • 100
  • 130
  • That's a great observation and a plausible one too. Thanks for sharing it. – Mehran Aug 23 '11 at 18:46
  • Perhaps, except that IMHO there really should be a big exception to the rule: a class or struct should be allowed to define extension members which operate on members of its own type, and in the case of structs, it should be possible for the "this" parameter to be either by value or reference. Such extension methods would allow immutable class types to behave more like value types with regard to initialization, and would allow normal 'method' syntax to be used on struct mutators without the risk of their being applied in read-only contexts. – supercat Nov 18 '11 at 00:00
  • @supercat If you could define an extension method in a class to act on itself, it wouldn't be an extension method would it? – Tim Lloyd Nov 18 '11 at 09:37
  • @chibacity: The methods I described would behave somewhat differently from instance methods. For reference types, it would be possible to invoke them on null objects whose compile-time type was known (allowing immutable reference types to behave like value types with a valid default value); for value types, it would be possible to distinguish methods which alter the left-hand operand (forbidding their use in read-only contexts) from those which do not. If you wouldn't call them "extension methods", what terminology would you use to describe them and distinguish them from instance methods? – supercat Nov 18 '11 at 15:59
  • @supercat Perhaps I am misunderstanding you. The whole purpose of extension methods is to extend existing types without altering them i.e. by "adding" methods. You are suggesting adding extension methods to the target types themselves - this isn't the design intention. – Tim Lloyd Nov 18 '11 at 16:06
  • @chibacity: To be sure, there might be other means of providing such functionalities (e.g. add a certain keyword or attribute to a class member to indicate that it should use static rather than virtual dispatch, thus skipping the null check, and/or add a keyword to struct members to indicate whether they mutate the underlying struct), but my point is that extension methods would allow a means of adding useful functionality to class types, and could allow a means of adding useful functionality to value types if one could declare the first parameter as "ref this". – supercat Nov 18 '11 at 16:11
  • @chibacity: From what I understand, the main "purpose" was to extend IEnumerable. My point is that because extension methods can do things instance methods cannot, self-extending methods could be somewhat useful with classes, and--I forgot to mention--extremely useful with interfaces. For example, one may have an interface where one of the methods would seldom need all its parameters. If the interface defines multiple overloads, every implementation must code all of them. A self-extension overload of the method would provide caller convenience without burdening implementers. – supercat Nov 18 '11 at 16:32
4

Take a look to this piece of the .NET C# specification:

When the first parameter of a method includes the this modifier, that method is said to be an extension method. Extension methods can only be declared in non-generic, non-nested static classes. The first parameter of an extension method can have no modifiers other than this, and the parameter type cannot be a pointer type.

And this fragment from Jon Skeet's answer:

It's not clear to me why all of these restrictions are necessary - other than potentially for compiler (and language spec) simplicity. I can see why it makes sense to restrict it to non-generic types, but I can't immediately see why they have to be non-nested and static. I suspect it makes the lookup rules considerably simpler if you don't have to worry about types contained within the current type etc, but I dare say it would be possible.

Community
  • 1
  • 1
Daniel Peñalba
  • 30,507
  • 32
  • 137
  • 219
1

Because the spec says so... Now there are probably good reasons why they wrote the spec this way.

The reason why they can't be declared in generic classes is quite obvious: given the way extension methods are called, where would you specify the type argument for the class?

The reason why it must be a static class is less obvious, but I think it makes sense. The main use case for static classes is to group helper methods together (e.g. Path, Directory, ProtectedData...), and extension methods are basically helper methods. It wouldn't make sense to be able to create an instance of Enumerable or Queryable, for example.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • I understand what spec says. I am interested to know why this design decisions are taken. – Mehran Aug 23 '11 at 16:19
  • @Mehran, that's precisely what I tried to explain in my answer... I didn't repeat what the spec says. – Thomas Levesque Aug 23 '11 at 16:21
  • 1
    Public extension methods would only be meaningful at a top-level static class, but the rules could sensibly have allowed extension methods to be declared in nested private or protected classes, with the proviso that such methods would only be usable where visible. For example, the code for class `Foo` might benefit from being able to define an extension method which uses a type that's private to `Foo`. Such an extension method would have no problem knowing what `T` to use, since the only code that could see it would have that type available. – supercat Dec 06 '13 at 21:44
  • @supercat in the absence of a "this" return type, extension methods are effectively the only way to write a fluid interface on a class that can be inherited. Given this, it would be nice to put the extension methods in the class they operate on so they could have access to private members and allow all the class code to be in once place. – Mike Marynowski Nov 14 '17 at 20:10