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

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

49460 次浏览

与 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 可以访问 OutterClass 的“ s”,我没有修改 Raymond 的代码(如上所述) ,所以请记住,“ string s;”是 private,因为没有指定其他访问权限。

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

  • 如果包含类型是泛型的,那么嵌套类型就会被包含类型有效地参数化,例如,Outer<int>.Nested不同于 Outer<string>.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 # 嵌套类默认为 private

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