C# 什么';从嵌套类访问封闭类中字段的最佳方式是什么?

C# 什么';从嵌套类访问封闭类中字段的最佳方式是什么?,c#,.net,inner-classes,C#,.net,Inner Classes,假设我在表单中有一个下拉列表,并且在这个类中有另一个嵌套类。 现在,从嵌套类访问此下拉列表的最佳方法是什么 与Java不同,嵌套类不是特殊的“内部类”,因此需要传递引用。Raymond Chen有一个例子描述了这里的差异: 下面是一个示例,其中嵌套类的构造函数被传递给外部类的实例以供以后参考 // C# class OuterClass { string s; // ... class InnerClass { OuterClass o_;

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

与Java不同,嵌套类不是特殊的“内部类”,因此需要传递引用。Raymond Chen有一个例子描述了这里的差异:

下面是一个示例,其中嵌套类的构造函数被传递给外部类的实例以供以后参考

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

}

请注意,内部类可以访问外部类的“
s
”,我没有修改Raymond的代码(如上所述),因此请记住“
字符串s;
”是
私有的,因为没有指定其他访问权限

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

  • 如果包含类型为泛型,则嵌套类型由包含类型有效地参数化,例如
    Outer。嵌套的
    Outer.nested的
    不同
  • 嵌套类型可以访问包含类型中的私有成员
与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";
        }
    }
}

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

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

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

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

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

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的特定问题,但通常对嵌套类很有帮助,就像这个“重复”问题:)

静态成员 因为到目前为止还没有人提到过它:根据您的情况,如果成员变量也可以是静态的,那么您可以通过以下方式访问它

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

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

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

c#嵌套类默认为私有类


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

请详细说明。示例将非常好。学习者,我已经在你的问题中添加了nestedclasses标记,因为有一个“我应该在什么时候使用嵌套类”的问题,将这两个标记分组比简单地使用C标记更有意义!能够做到这一点(使用标准语法)的前景非常有趣。。。在行为上有点像闭包。毫无疑问,这种特性会被滥用,直到它成为反模式(如果存在的话)=(这是一个有趣的想法,与其他答案有点不同。但是,我非常确定您不能实例化现有对象实例的子类,因此如果您已经有一个
外部
实例,并且想要一个与您现有的
外部
实例对应的
嵌套的
实例,我认为这是行不通的。这里的问题是,创建“Nested”的新实例将调用外部类的“ctor”,很可能导致堆栈溢出。(大约7年后…)你知道为什么外部类不能访问嵌套类的私有成员或受保护成员,就像嵌套类可以访问外部类成员一样吗?有时这会很有用,我想知道我的设计中是否有缺陷。@GDS:我不知道为什么会做出这样的设计决定,但通常是这样做的nse对我来说。如果你将嵌套类设置为私有,那么将成员设置为内部或公共成员也没关系。没错,但在某些情况下,你不希望内部或甚至公共嵌套类的私有和受保护成员被外部类看到吗?有没有潜在的缺陷?@GDS:我只能说我我自己没有遇到过这些情况。我无法推测设计的确切原因。这似乎还有一个优点,即与Java不同,内部类的实例可以访问外部类的任何实例的私有成员,而不仅仅是创建内部类实例的外部类实例(即
Form1 form=new Form1();new嵌套(f