Why Aren't C# Static Class Extension Methods Supported

Why aren't C# static class extension methods supported?

the C# team could have implemented this kind of functionality. Is there some philosophical reason why it isn't supported?

There's no technical reason, and no philosophical reason. However, as I often point out, I don't have to provide a justification for not doing a feature. Features aren't cheap; they are extremely expensive and they must not only justify their own cost, they must justify the opportunity cost of not doing the hundred other features we could have done with that budget. We must justify the cost of features to our stakeholders, but we need not justify saving time and effort by not implementing features that don't meet our bar.

In particular, the proposed feature does nothing for LINQ; extension methods were added to make LINQ work. Anything that didn't make LINQ work was very hard to get into C# 3.0; we had a lot of work on the schedule and not much time to do it in. (I was surprised that automatic properties made it in.) Cutting an unnecessary feature before even designing it saved a lot of time and effort that was spent on other things that do make LINQ work.

In short: the suggested feature has never met our bar for net benefit over cost, and we've always had more important features to spend our limited time and effort on.

Why can't static method in non-static class be an extension method?

Eric Lippert will probably weigh in with a really good answer on this one, but the gist of it will probably be:

We decided it would be easier on both programmers and the compiler if we limit the number of places that you have to look for extension methods.

This policy tends to force users to put all of their extension methods into a few specific classes that are designated for this purpose.

Why are extension methods only allowed in non-nested, non-generic static class?

Why are extension methods only allowed in non-nested, non-generic static class?

As Pratik points out, the question we face is not "why are extension methods not allowed in nested or generic classes?" The question we face as language designers is "why should extension methods be allowed in nested or generic classes?"

Unless the feature is justified by some real-world user need, we're not going to take on the considerable costs of designing, implementing, testing, documenting and maintaining the feature.

Basically, extension methods were designed to make LINQ work. Anything that didn't contribute to making LINQ work was cut. LINQ only needs extension methods in static, non-generic, non-nested classes to work, so that's what we designed and implemented.

If you have a scenario where extension methods would be useful in non-static, generic, or nested classes then I'm happy to take a look at the scenario. The more real-world scenarios we get, the more likely it is that we'll make a feature in some hypothetical future language that benefits those scenarios.

Is it useless to consider extension methods in nested, generic static class?

No, it is a great idea to consider it. We would be remiss in our duties if we did not consider it. We considered it carefully for a long time and decided that on the basis of that consideration, the costs of doing the feature were not justified by the benefits accrued.

Static extension methods

In short, no, you can't.

Long answer, extension methods are just syntactic sugar. IE:

If you have an extension method on string let's say:

public static string SomeStringExtension(this string s)
{
//whatever..
}

When you then call it:

myString.SomeStringExtension();

The compiler just turns it into:

ExtensionClass.SomeStringExtension(myString);

So as you can see, there's no way to do that for static methods.

And another thing just dawned on me: what would really be the point of being able to add static methods on existing classes? You can just have your own helper class that does the same thing, so what's really the benefit in being able to do:

Bool.Parse(..)

vs.

Helper.ParseBool(..);

Doesn't really bring much to the table...

c# extend String Class with static method

No, you can't.

For more information, and an explanation, see these earlier questions:

  • Can I add extension methods to an existing static class?
  • Static extension methods
  • Why aren't C# static class extension methods supported?

Error CS1109 Extension methods must be defined in a top level static class; Patterns is a nested class

You can't - there are no "extension properties".

The best you can get - s.Patterns().NumbersOnly() by introducing intermediate class to return from Patterns extension method.

Sample puts all methods in single class, but you can organize them any way you want to different classes as long as extensions methods satisfy "defined in a top level static class":

public static class StringExtensions
{
public class PatternsX
{
public string Value {get;set;}
}

public static PatternsX Patterns(this string s)
{
return new PatternsX { Value = s};
}

public static string NumbersOnly(this PatternsX s)
{
return new String(s.Value.Where(Char.IsDigit).ToArray());
}
}

....
Console.WriteLine("123ver".Patterns().NumbersOnly()); // results in 123

Do extension methods benefit in any practical way from being a part of a static class vs. [theoretically] a part of a namespace?

Perhaps you will find a satisfactory answer in Eric Lippert's blog post Why Doesn't C# Implement "Top Level" Methods? (in turn prompted by SO question Why C# is not allowing non-member functions like C++), whence (my emphasis):

I am asked "why doesn't C# implement feature X?" all the time. The
answer is always the same: because no one ever designed, specified,
implemented, tested, documented and shipped that feature. All six of
those things are necessary to make a feature happen. All of them cost
huge amounts of time, effort and money. Features are not cheap, and we
try very hard to make sure that we are only shipping those features
which give the best possible benefits to our users given our
constrained time, effort and money budgets.

I understand that such a general answer probably does not address the
specific question.

In this particular case, the clear user benefit was in the past not
large enough to justify the complications to the language which would
ensue. By restricting how different language entities nest inside each
other we (1) restrict legal programs to be in a common, easily
understood style, and (2) make it possible to define "identifier
lookup" rules which are comprehensible, specifiable, implementable,
testable and documentable.

By restricting method bodies to always be inside a struct or class, we make it easier to reason about the meaning of an unqualified
identifier used in an invocation context; such a thing is always an
invocable member of the current type (or a base type).

Static extension methods and Project Roslyn

You cannot create an instance of a static type. var c = new Console(); does not work. Therefore, you cannot have an argument with a static type. In Console c, what would c be? The syntax of your proposed static type extension method would have to be something like this:

public static void WriteLineInGreen(static Console, string formatString,
params object[] args)
{
Console.ForeGround = ConsoleColor.Green;
Console.WriteLine(formatString, args);
}

I think that the language specification changes related to Roslyn are due to the fact that language specification inconsistencies and inaccuracies have been found while working on Roslyn. It seems not very plausible to me that any new C# language features are related to Roslyn.

Update: Well, I was wrong on this last point. As @svick points out in his comment, the much better structure of the new compiler makes it easier to implement language changes.

Another important reason is that the language and compiler development has become open source. Microsoft invites the community to participate. (See: C# 7 Work List of Features.)

Extension Methods with Custom Classes

Extension methods require an instance of an object. You'll have to new up a CustomClass to use it.

var custom = new CustomClass();
custom.DoSomething();

See this answer as to why that is.



Related Topics



Leave a reply



Submit