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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/185124/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:02:47  来源:igfitidea点击:

What's the best way of accessing field in the enclosing class from the nested class?

c#.netinner-classes

提问by

Say if I have a dropdown in a form and I have another nested class inside of this class . Now what's the best way to access this dropdown from the nested class?

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

回答by Ray Hayes

Unlike Java, a nested class isn't a special "inner class" so you'd need to pass a reference. Raymond Chen has an example describing the differences here : C# nested classes are like C++ nested classes, not Java inner classes.

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

Here is an example where the constructor of the nested class is passed the instance of the outer class for later reference.

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

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

}

Note that the InnerClass can access the "s" of the OuterClass, I didn't modify Raymond's code (as I linked to above), so remember that the "string s;" is privatebecause no other access permission was specified.

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

回答by Jon Skeet

Nested types aren't like inner classes in Java - there's no inherent instance of the containing type. (They're more like static nested classes in Java.) They're effectively separate classes, with two distinctions:

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

  • If the containing type is generic, the nested type is effectively parameterised by the containing type, e.g. Outer<int>.Nestedisn't the same as Outer<string>.Nested.
  • Nested types have access to private members in the containing type.
  • 如果包含类型是泛型,则嵌套类型由包含类型有效地参数化,例如Outer<int>.NestedOuter<string>.Nested.
  • 嵌套类型可以访问包含类型中的私有成员。

回答by Jason Kresowaty

Unlike Java, in C# there is no implicit reference to an instance of the enclosing class.

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

You need to pass such a reference to the nested class. A typical way to do this is through the nested class's constructor.

您需要将这样的引用传递给嵌套类。执行此操作的典型方法是通过嵌套类的构造函数。

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

回答by mannu

You could pass the enclosing class as a parameter to the nested class constructor, like this:

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

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

Nested classes are generally not recommended and should be private and/or internal. They are, in my opinion, useful sometimes though.

通常不推荐嵌套类,它应该是私有的和/或内部的。不过,在我看来,它们有时很有用。

回答by questzen

Correct me if I am wrong, you are trying to process the outer control from inner class hence you ran into this. A better way of doing this would be to handle affairs in a event driven fashion. Use an Observer pattern, Register a listener on the outer control (your nested/inner class will be the listener). Makes life simpler. I am afraid that this is not the answer you were expecting!

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

回答by kmote

One other method, which is useful under certain circumstances, is to derive the nested class off of the outer class. Like so:

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

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

I have used this technique especially in the context of Structured Unit Tests. (This may not apply to the OP's particular question, but it can be helpful with nested classes in general, as in the case of this "duplicate" question: " Can i access outer class objects in inner class")

我特别在Structured Unit Tests的上下文中使用了这种技术。(这可能不适用于 OP 的特定问题,但它通常对嵌套类很有帮助,就像这个“重复”问题的情况一样:“我可以访问内部类中的外部类对象吗”)

回答by Levite

Static Members

静态成员

Since no one has mentioned it so far: Depending on your situation, if the member variable can also be static, you could simply access it in following way.

由于到目前为止没有人提到它:根据您的情况,如果成员变量也可以是static,您可以通过以下方式简单地访问它。

class OuterClass
{
    private static int memberVar;

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

Sidenote:I marked memberVarpurposefully (and redundantly) as privateto illustrate the given ability of the nested class to access private members of it's outer class.

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

Caution / Please consider

注意/请考虑

In some situationsthis might be the easiest way/workaround to get access, but ...

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

  • Static also means, that the variable will be shared across all instance objects, with all the downsides/consequences there are (thread-safety, etc.)

  • Static also means, that this will obviously not work if you have more than one instance of the parent's class and the variable should hold an individual value for each instance

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

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

So in most cases you might wanna go with a different approach ...

所以在大多数情况下,你可能想要采用不同的方法......

Passing a Reference

传递引用

As most people have suggested (and because it is also the most correct answer), here an example of passing a reference to the outer class' instance.

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

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

回答by Hamid Jolany

send the master class as an constructor parameter to the nested (inner) class.

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