为什么不允许在嵌套类的扩展方法定义是什么? [关闭](Why not allow Extensi

2019-06-26 05:56发布

我会觉得很方便/逻辑写我exensions一类的嵌套类。 最主要的原因是我可以简单地命名该类Extensions ,让它的外部命名范围给它一个独特的类型名称的编译器。

什么是技术上的原因不允许这样的:

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);
      }
   }
}

而现在我要创建一个单独的独立类。

更新/注:我不想象,这是一个事实的内部类会影响的扩展方法的有效性范围。 我只是想解决的实际问题,编码一个单独的类具有一个独立的名字。

Answer 1:

这里的关键点是, 嵌套类可以在外部类访问私有字段

所以,下面的代码工作:

public class Foo
{
    private bool _field;

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

在这里,你明确地传递一个类的实例,静态方法是允许访问私有字段...似乎是合理的:

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

然而,尽管扩展方法只是静态方法的替代语法,它们被调用的方式非静态实例方法相同。

现在,如果扩展方法在嵌套类被允许,他们其实可以访问私有字段,他们会更接近于实例方法。 这可能会导致一些意想不到的后果。

总之,如果这被允许:

public class Foo
{
    private bool _field;

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

然后,你可以写下面的代码,使扩展方法表现得有点更像是一个实例方法比它应该是:

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

编辑作为评论的结果

为什么是一个坏主意的扩展方法等同于实例方法?

在埃里克利珀的话 (重点煤矿):

所以,是的,经常听到的批评,“扩展方法不是面向对象”是完全正确的,但也相当无关。 扩展方法肯定不是面向对象的。 他们把从声明数据的代码操纵数据远代码, 他们不能打破封装和交谈,他们似乎是,他们不继承发挥好,等方法的对象的私有状态 。 他们是在一个方便的面向对象的装扮过程编程。



Answer 2:

没有技术的原因吧 - 只要实用。 如果您有在范围上仅限于单个类的扩展方法,只是将其定义为在类常规静态方法和删除“本”。 扩展是跨越几类共享。



Answer 3:

我想背后不允许这件事情的想法是因为扩展方法适用于整个命名空间的所有实体。

如果您将创建一个嵌套的扩展方法的类,那么这将是只适用于它嵌套类。 在这种情况下,它不是指向创建扩展方法。 然后,任何正常的非扩展方法会做。



文章来源: Why not allow Extension method definition in nested class? [closed]