Alex Rivera | Logout

Why not allow Extension method definition in nested class?

Asked 2012-07-12T01:20:20.237
15

I would find it convenient/logical to write my exensions for a class in a nested class. The main reason is I could simply name that class Extensions and let it's outer naming scope give it a unique type name for the compiler.

What is the technical reason to disallow something like:

public class Foo
{
   ObjectSet<Bar> Bars { get; set; }

   public static class Extensions
   {
      public static Bar ByName(this ObjectSet<Bar> bars, string name)
      {
         return bars.FirstOrDefault(c => c.Name == name);
      }
   }
}

Whereas now I have to create a separate free standing class.

Update/Note: I wasn't imagining that the fact it was an inner class would affect the scope of availability of the extension method. I only wanted to address the practical coding issue a separate class with a separate name.

Edit
Report

1 Answer

10

The key point here is that nested classes can access private fields in the outer class.

So the following code works:

public class Foo
{
    private bool _field;

    public static class Extensions
    {
        public static bool GetField(Foo foo)
        {
            return foo._field;
        }
    }
}

Here you are explicitly passing in an instance of the class, and a static method is allowed to access a private field... seems reasonable:

bool fieldValue = Foo.Extensions.GetField(new Foo());

However, although extension methods are just an alternative syntax for static methods, they are invoked the same way as non-static instance methods.

Now if extension methods were allowed in nested classes, they could in fact access private fields, and they would be that much closer to instance methods. This could lead to some unintended consequences.

In summary, if this were allowed:

public class Foo
{
    private bool _field;

    public static class Extensions
    {
        public static bool GetField(*this* Foo foo) // not allowed, compile error.
        {
            return foo._field;
        }
    }
}

Then you could write the following code, making the extension method behave a bit more like an instance method than it should be:

var foo = new Foo();
var iGotAPrivateField = foo.GetField();

Edit as a result of comments

Why is it a bad idea for extension methods to be equivalent to instance methods?

In Eric Lippert's words (emphasis mine):

So, yes, the oft-heard criticism that "extension methods are not object-oriented" is entirely correct, but also rather irrelevant. Extension methods cert

answered 2012-08-20T12:39:57.277

Your Answer