Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not allow Extension method definition in nested class? [closed]

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.

like image 502
Aaron Anodide Avatar asked Jul 12 '12 01:07

Aaron Anodide


People also ask

Can sealed class have extension methods?

A class can be sealed by using the sealed keyword. The keyword tells the compiler that the class is sealed, and therefore, cannot be extended. No class can be derived from a sealed class.

Can we define extension method for a class?

You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself.

Can we define extension method for class which itself is a static class?

No. Extension methods require an instance variable (value) for an object. You can however, write a static wrapper around the ConfigurationManager interface. If you implement the wrapper, you don't need an extension method since you can just add the method directly.

Can we override extension method?

Extension methods cannot be overridden the way classes and instance methods are. They are overridden by a slight trick in how the compiler selects which extension method to use by using "closeness" of the method to the caller via namespaces.


1 Answers

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 certainly are not object-oriented. They put the code that manipulates the data far away from the code that declares the data, they cannot break encapsulation and talk to the private state of the objects they appear to be methods on, they do not play well with inheritance, and so on. They're procedural programming in a convenient object-oriented dress.

like image 99
Zaid Masud Avatar answered Sep 21 '22 05:09

Zaid Masud