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

时间:2008-10-08 22:12:49

标签: c# .net inner-classes

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

9 个答案:

答案 0 :(得分:71)

与Java不同,嵌套类不是特殊的“内部类”,因此您需要传递引用。 Raymond Chen有一个例子来描述这里的差异:C# nested classes are like C++ nested classes, not Java inner classes

这是一个示例,其中嵌套类的构造函数传递外部类的实例以供以后引用。

// 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;”是{{ 1}}因为没有指定其他访问权限。

答案 1 :(得分:30)

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

  • 如果包含类型是通用的,则嵌套类型由包含类型有效地参数化,例如, Outer<int>.NestedOuter<string>.Nested不同。
  • 嵌套类型可以访问包含类型中的私有成员。

答案 2 :(得分:12)

与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";
        }
    }
}

答案 3 :(得分:8)

静态成员

由于目前还没有人提及它:根据您的情况,如果成员变量也可以静态,您可以通过以下方式访问它。 / p>

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

答案 4 :(得分:4)

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

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

我特别在Structured Unit Tests的背景下使用过这种技术。 (这可能不适用于OP的特定问题,但它对于嵌套类通常很有用,就像这个“重复”问题的情况一样:“Can i access outer class objects in inner class”)

答案 5 :(得分:1)

如果我错了,请纠正我,你正试图从内部类处理外部控件,因此你遇到了这个问题。更好的方法是以事件驱动的方式处理事务。使用Observer模式,在外部控件上注册一个监听器(您的嵌套/内部类将是监听器)。让生活更简单。我担心这不是你期待的答案!

答案 6 :(得分:0)

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

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

通常不建议使用嵌套类,并且应该是私有和/或内部类。在我看来,它们虽然有时很有用。

答案 7 :(得分:0)

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

答案 8 :(得分:0)

上面有一个很好的答案,但我喜欢写……

c# 嵌套类默认是私有的

包含类的私有如果你想使用它必须是公共的