嵌套类:从内部类访问外部类的非静态字段.可能吗? [英] Nested classes: accessing non-static fields of the outer class from inner class. Is it possible?

查看:64
本文介绍了嵌套类:从内部类访问外部类的非静态字段.可能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以从内部类访问外部类的非静态(常规)字段?例如:

Is it possible to access non-static (normal) fields of the outer class from the inner class?. E.g.:

...
public class OuterClass
{
   public int OuterField = 10;
   
   InnerClass InnerObject = new InnerClass();

   public class InnerClass
   {
      public InnerField = 20;
      int AddInnerAndOuter()
      {
         return InnerField + OuterField;
      }
   }
}
...



编译器错误为:



The compiler error is:

error CS0038: Cannot access a non-static member of outer type 'OuterClass' via nested type 'OuterClass.InnerClass'



好的.我试图了解编译器的答案.但是,我是否真的必须使OuterField静态以从InnerClass访问它,从而使整个OuterClass实例组都依赖于相同的静态OuterField值?还是我必须将OuterField引用传递给InnerClass才能访问它?例如:



Ok. I''m trying to understand the compiler answer. But do I really have to make OuterField static to access it from InnerClass, and thus make whole group of OuterClass instances dependent on the same value of static OuterField? Or do I have to pass OuterField reference to InnerClass to access it? E.g.:

...
public class OuterClass
{
   public int OuterField = 10;

   InnerClass InnerObject = new InnerClass();
   InnerObject.OuterFieldRef = OuterField;

   public class InnerClass
   {
      public OuterFieldRef;
      public InnerField = 20;

      int AddInnerAndOuter()
      {
         return InnerField + OuterFieldRef;
      }
   }
...
}



问题是:是否有一种更优雅,更简单的方法可以从内部类访问非静态外部字段而不将其设置为静态,从而使任何OuterClass实例唯一?



The question is: Is there a more elegant and simpler way to access non-static outer fields from inner class without make them static and thus having any OuterClass instance unique?

推荐答案

哦……首先,非静态方法称为实例方法",而不是普通"方法.顺便说一下,这是关键.现在,您的访问问题与一个类是另一类的内部类这一事实无关.

当你说

Oh… First, non-static methods called "instance methods", not "normal". This is the key, by the way. Now, your problem of access has nothing to do with the fact that one class is an inner class of another.

When you say

return InnerField + OuterField;



你真的说



you really say

return this.InnerField + someInstance.OuterField;



但是什么是someInstance?哪有这回事.没有某些实例,字段OuterField不存在.

你看,你在问什么与优雅"或简单"无关.这是关于了解您想阅读的字段,对象的信息.以及为什么.您的第二个样本根本没有任何意义.您声明没有类型的名称;它不会编译.

现在,还有诸如访问修饰符之类的方面.内部类可以访问外部的成员,但是外部类只能访问内部的内部或公共成员.同样,它与静态方法或实例方法无关.访问的这两个方面是正交的,独立的.

—SA



but what is someInstance? There is no such thing. The field OuterField does not exist without some instance.

You see, what are you asking about has nothing to do with "elegance" or "simplicity". This is about understanding what field you want to read, of what object. And why. Your second sample makes no sense at all; you declare names without types; it won''t compile.

Now, there is also such aspect as access modifier. The inner class can access the members of the outer, but the outer class can only access internal or public members of the inner. Again, it has nothing to do with static or instance method. These two aspects of access are orthogonal, independent.

—SA


感谢您的反馈.好的.我承认我是在赶时间写这篇文章.当然,我的示例将无法编译.我在代码段文本的前后都用"..."标记了代码段.我没有给出整个示例程序.但是...请不要把我的榜样完全丢掉.我认为这值得关注.除适当标记的行外,下面的程序将编译.

Thanks for the feedback. Ok. I admit I was writting this text in a hurry. Of course my example will not compile. I marked my code snippets with "..." before and after the snippet text. I didn''t give the whole example program. But... please don''t throw my example with the rubbish completely. I think it deserves a bit of attention. The program below will compile except for the line which is appropriately marked.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OuterInner
{
    public class OuterClass
    {
        private int OuterField = 10;

        // Below the creation of InnerClass instance is made, so with the  
        // creation of OuterInstance InnerInstance will be created automatically.
        public InnerClass InnerInstance = new InnerClass(); 


        public class InnerClass
        {
            public void PrintOuterField(OuterClass OuterInstance)
            {
                // The line below will not compile. I thought inner instance 
                // of inner class can access directly to fields of instance of
                // outer class provided that inner class are instantiate in
                // the body of outer class. But.. probably it turns out
                // impossible to achieve.
                Console.WriteLine(OuterField); // <- this line will not compile
                
                // On the other hand this line WILL compile despite
                // ''OuterField'' is private. This is obvious of course because
                // inner class (as you mentioned) has access to members of the
                // outer class.
                Console.WriteLine(OuterInstance.OuterField);  
            }
        }
        
    }
    
    public class Program
    {
        static void Main(string[] args)
        {
            // The line below creates instance of OuterClass so from that moment
            // OuterInstance (and InnerInstance) exists.
            OuterClass OuterInstance = new OuterClass();  
            OuterInstance.InnerInstance.PrintOuterField(OuterInstance);
            Console.ReadLine();
        }
    }
    
}



如您所见,我在"Main"方法中创建了OuterClass实例,而InnerClass实例是在OuterClase主体中创建的,(我认为很重要)InnerClass实例是在实例化OuterClass时自动创建的.因此,简单地说,在创建OuterClass实例之后,我们实际上同时拥有OuterClass和InnerClass实例.当然,我可以将"OuterField"设为静态.从任何地方访问该字段都将更加容易(当然,只要它是公共的(最终是内部的)).但是,我试图找到一种解决方案(再次重复该单词),以优雅地摆脱使用静态字段的作用,以使OuterClass的每个实例与其兄弟姐妹完全不同.其实我有这样的情况:
集合的集合.我们将它们命名为SuperCollection和SubCollections.首先,我不希望SuperCollection类成为或具有静态外观的字段(可以这么说). SubCollection实例具有他们所有人共享的一种信息(但我想出于已知的原因,我也不想将此类信息存储在静态字段中).我决定创建一个在SuperCollection类的主体中存储此信息的字段,以使每个SubCollection实例在实例化SuperCollection之后都可以使用它,而无需在SubCollection的每个实例中存储对SuperCollection实例的任何引用.到目前为止,要使SuperCollection和SubCollection类都完全非静态,我没有找到任何其他解决方案,但是(如上所述),在每个SubCollection中都制作了另一个字段,其中包含有关对其容器"的引用的信息,以访问所提到的共享SuperCollecttion实例引用信息字段.它允许OuterCollection(当然还有InnerCollections)的任何实例都是唯一的,但是由于每个SubCollection实例中都有其他引用,因此我认为这样的解决方案不是很方便(并且...优雅).也许我尝试以另一种方式问这个问题:在外部类中,有一种方法可以为嵌套类创建某种全局字段(不使用静态修饰符),因此嵌套类的每个实例都可以在之后透明地使用此全局字段"实例化外部类?如果我对概念有误或感到困惑,请赐教.



As you see I created OuterClass instance in the ''Main'' method whereas InnerClass instance was created in the body of the OuterClase and (what is important I think) the InnerClass instance was created automatically in the moment when the OuterClass was instantiating. Therefore briefly speaking after creating instance of OuterClass we have actually both OuterClass and InnerClass instances. Of course I could make the ''OuterField'' static. It would be easier to access such field from everywhere (of course provided that it would be public (eventually internal)). But I tried to find a solution to (I repeat this word again) to elegantly get rid of playing with static fields to make every instance of OuterClass completely distinct from its siblings. Actually I have such situation:
collection of collections. Let''s name them SuperCollection and SubCollections. First I don''t want SuperCollection class to be or to have fields with static apparition (so to speak). SubCollection instances have e.g. one information shared by them all (but again I don''t want to store such info in a static field, I think for known reasons). I decided to create a field storing this information in the body of the SuperCollection class in order to every SubCollection instance could make use of it after instantiate SuperCollection without need of storing any reference to SuperCollection instance in every instance of SubCollection. To make completely non-static both SuperCollection and SubCollection classes so far I haven''t found any other solution but (as mentioned above) to make another field in every SubCollection containing information about reference to its "container" to get access to mentioned shared SuperCollecttion instance reference-info field. It allows any instance of OuterCollection (and of course InnerCollections) to be unique but such solution is not very convenient (and... elegant) in my opinion on account of additional reference in every SubCollection instance. Maybe I try to ask the question in another way: In outer class is there a way to create some kind of global fields (without using static modifier) for nested classes, so every instance of nested class could use this "global field" transparently after instantiating outer class? If I''m wrong or confuse notions, please enlighten me.


为什么不能简单地将外部类指针作为构造函数参数传递给内部类?请参阅下面的我经过稍微修改的代码示例.您的示例可以正常编译,并且逻辑现在看起来很好.

-莎拉

Why could you not simply pass the outer class pointer as a constructor argument to the inner class? See my slightly modified code sample below. Your sample compiles fine and logic seems fine now.

-Sarah

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace OuterInner
{
    public class OuterClass
    {
        private int OuterField = 10;
 
        // Below the creation of InnerClass instance is made, so with the  
        // creation of OuterInstance InnerInstance will be created automatically.
        public InnerClass InnerInstance = new InnerClass(); 
 

        public class InnerClass
        {
			OuterClass m_oOuter = null;

			public InnerClass(OuterClass oOuter)
			{
				// Save the outer class pointer for use in a bit.
				this.m_oOuter = oOuter;
			}

            public void PrintOuterField(OuterClass OuterInstance)
            {
                // The line below will not compile. I thought inner instance 
                // of inner class can access directly to fields of instance of
                // outer class provided that inner class are instantiate in
                // the body of outer class. But.. probably it turns out
                // impossible to achieve.
                Console.WriteLine(this.m_oOuter); // <- this line will not compile
                
                // On the other hand this line WILL compile despite
                // 'OuterField' is private. This is obvious of course because
                // inner class (as you mentioned) has access to members of the
                // outer class.
                Console.WriteLine(OuterInstance.OuterField);  
            }
        }
        
    }
    
    public class Program
    {
        static void Main(string[] args)
        {
            // The line below creates instance of OuterClass so from that moment
            // OuterInstance (and InnerInstance) exists.
            OuterClass OuterInstance = new OuterClass();  
            OuterInstance.InnerInstance.PrintOuterField(OuterInstance);
            Console.ReadLine();
        }
    }
}


这篇关于嵌套类:从内部类访问外部类的非静态字段.可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆