从嵌套类访问封闭类中字段的最佳方法是什么?

假设我在表单中有一个下拉菜单,并且该类中还有另一个嵌套类。现在,从嵌套类访问此下拉列表的最佳方法是什么?

Jim Fell asked 2019-11-07T18:28:21Z
8个解决方案
74 votes

与Java不同,嵌套类不是特殊的“内部类”,因此您需要传递引用。 Raymond Chen在这里有一个描述差异的示例:C#嵌套类就像C ++嵌套类,而不是Java内部类。

这是一个将嵌套类的构造函数传递给外部类的实例以供以后参考的示例。

// C#
class OuterClass 
{
    string s;
    // ...
    class InnerClass 
    {
       OuterClass o_;
       public InnerClass(OuterClass o) { o_ = o; }
       public string GetOuterString() { return o_.s; }
    }
    void SomeFunction() {
        InnerClass i = new InnerClass(this);
        i.GetOuterString();
    }

}

请注意,InnerClass可以访问OuterClass的“ s”,我没有修改Raymond的代码(正如我上面所链接的),因此请记住,“ string s;”为private,因为未指定其他访问权限。

Ray Hayes answered 2019-11-07T18:28:46Z
31 votes

嵌套类型不同于Java中的内部类-包含类型没有固有的实例。 (它们更像Java中的静态嵌套类。)它们实际上是分离的类,有两个区别:

  • 如果包含类型是通用类型,则嵌套类型可以通过包含类型有效地参数化,例如 Outer<int>.NestedOuter<string>.Nested不同。
  • 嵌套类型可以访问包含类型中的私有成员。
Jon Skeet answered 2019-11-07T18:29:24Z
12 votes

与Java不同,在C#中,没有隐式引用封闭类的实例。

您需要将这样的引用传递给嵌套类。 一种典型的方法是通过嵌套类的构造函数。

public partial class Form1 : Form
{
    private Nested m_Nested;

    public Form1()
    {
        InitializeComponent();

        m_Nested = new Nested(this);
        m_Nested.Test();
    }

    private class Nested
    {
        private Form1 m_Parent;

        protected Form1 Parent
        {
            get
            {
                return m_Parent;
            }
        }

        public Nested(Form1 parent)
        {
            m_Parent = parent;
        }

        public void Test()
        {
            this.Parent.textBox1.Text = "Testing access to parent Form's control";
        }
    }
}
Jason Kresowaty answered 2019-11-07T18:29:54Z
9 votes

静态成员

由于到目前为止还没有人提到它:根据您的情况,如果member变量也可以是静态的,则可以按以下方式简单地访问它。

class OuterClass
{
    private static int memberVar;

    class NestedClass 
    {
        void SomeFunction() { OuterClass.memberVar = 42; }
    }
}

旁注:我有目的地(且多余地)将memberVar标记为private,以说明嵌套类访问其外部类的私有成员的既定能力。

注意/请考虑

在某些情况下,这可能是获得访问权限的最简单方法/解决方法,但是...

  • 静态还意味着,该变量将在所有实例对象之间共享,并具有所有缺点/后果(线程安全性等)。

  • 静态还意味着,如果您有多个父类的实例,并且变量应该为每个实例保存一个单独的值,那么这显然将不起作用

因此,在大多数情况下,您可能想采用其他方法...

传递参考

正如大多数人所建议的那样(并且因为它也是最正确的答案),这里是将引用传递给外部类实例的示例。

class OuterClass
{
    private int memberVar;
    private NestedClass n;

    OuterClass()   { n = new NestedClass(this); }


    class NestedClass
    {
        private OuterClass parent;

        NestedClass(OuterClass p) { parent = p; }
        SomeFunction() { parent.memberVar = 42; }
    }
}
Levit answered 2019-11-07T18:31:18Z
4 votes

在某些情况下有用的另一种方法是从外部类派生嵌套类。 像这样:

class Outer()
{
    protected int outerVar;
    class Nested() : Outer
    {
        //can access outerVar here, without the need for a 
        // reference variable (or the associated dot notation).
    }
}

我特别在结构化单元测试的上下文中使用了此技术。 (这可能不适用于OP的特定问题,但通常对嵌套类有帮助,例如在以下“重复”问题的情况下:“我可以访问内部类中的外部类对象”)

kmote answered 2019-11-07T18:31:50Z
1 votes

如果我错了,请纠正我,您正在尝试从内部类处理外部控件,因此您遇到了这种情况。 更好的方法是以事件驱动的方式处理事务。 使用观察者模式,在外部控件上注册一个侦听器(您的嵌套/内部类将是侦听器)。 使生活更简单。 恐怕这不是您期望的答案!

questzen answered 2019-11-07T18:32:15Z
0 votes

您可以将封闭的类作为参数传递给嵌套类的构造函数,如下所示:

private NestedClass _nestedClass;
public ParentClass() 
{
   _nestedClass = new NestedClass(this);
}

通常不建议使用嵌套类,而应使用私有类和/或内部类。 我认为它们有时还是有用的。

mannu answered 2019-11-07T18:32:47Z
0 votes

将主类作为构造函数参数发送到嵌套(内部)类。

Hamid Jolany answered 2019-11-07T18:33:11Z
translate from https://stackoverflow.com:/questions/185124/whats-the-best-way-of-accessing-field-in-the-enclosing-class-from-the-nested-cl