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

时间:2022-01-14 02:49:32

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?

比方说,如果我有一个下拉列表,我在这个类里面有另一个嵌套的类。从嵌套类中访问下拉菜单的最佳方式是什么?

8 个解决方案

#1


62  

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 private because no other access permission was specified.

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

#2


23  

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>.Nested isn't the same as Outer<string>.Nested.
  • 如果包含类型为泛型,则嵌套类型有效地由包含类型(例如外部 )进行参数化。嵌套与外部 .嵌套的不一样。
  • Nested types have access to private members in the containing type.
  • 嵌套类型可以访问包含类型中的私有成员。

#3


10  

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

#4


7  

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.

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

class OuterClass
{
    private static int memberVar;

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

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

Sidenote:我有意地将memberVar标记为private(并且冗余),以说明嵌套类访问其外部类的私有成员的能力。

Caution / Please consider

In some situations this 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; }
    }
}

#5


3  

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 ")

我已经使用了这种技术,特别是在结构化单元测试的上下文中。(这可能不适用于OP的特定问题,但对于嵌套类来说,通常是有帮助的,就像在“duplicate”问题中:“我可以访问内部类中的外部类对象吗?”)

#6


1  

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!

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

#7


0  

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.

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

#8


0  

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

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

#1


62  

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 private because no other access permission was specified.

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

#2


23  

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>.Nested isn't the same as Outer<string>.Nested.
  • 如果包含类型为泛型,则嵌套类型有效地由包含类型(例如外部 )进行参数化。嵌套与外部 .嵌套的不一样。
  • Nested types have access to private members in the containing type.
  • 嵌套类型可以访问包含类型中的私有成员。

#3


10  

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

#4


7  

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.

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

class OuterClass
{
    private static int memberVar;

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

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

Sidenote:我有意地将memberVar标记为private(并且冗余),以说明嵌套类访问其外部类的私有成员的能力。

Caution / Please consider

In some situations this 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; }
    }
}

#5


3  

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 ")

我已经使用了这种技术,特别是在结构化单元测试的上下文中。(这可能不适用于OP的特定问题,但对于嵌套类来说,通常是有帮助的,就像在“duplicate”问题中:“我可以访问内部类中的外部类对象吗?”)

#6


1  

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!

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

#7


0  

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.

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

#8


0  

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

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