问题
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.
回答1:
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.
回答2:
There is no technical reason for it - just practical. If you have an extension method that is limited in scope to a single class, just define it as a regular static method in your class and remove the 'this'. Extensions are for sharing across several classes.
回答3:
I guess the idea behind disallowing this thing is because Extension Methods are applied for all entities across the namespace.
If you will create a nested Extension Methods class then it will be applicable only to class where it is nested. In that case its not point creating an extension method. Then any normal non-extension method would do.
来源:https://stackoverflow.com/questions/11443842/why-not-allow-extension-method-definition-in-nested-class