菜鸟请教:在嵌套类里如何使用外部类的非静态成员?

清风明月逍遥云 2019-05-30 05:36:39
我在主窗体的类(Form1)内部建了一个新类(假设名字是AAA)。AAA内部想改变Form1的一个标签控件label1.Text的内容,然而出现错误警告:不能在嵌套类里使用外部类的非静态成员!
我百度了一下,据说可以用构造函数解决此问题,但是我试着做了一下,虽然没有警告了,并且可以编译执行了,但执行的末期,VS2013却崩溃了。而假如我注释掉AAA内部用来改变label1.Text内容的语句,则不会崩溃。

我是搞嵌入式的,对上位机软件不熟悉。难道嵌套类不常用吗? C#或者.Net没有现成的指令吗?
另外,本论坛没有搜索功能吗?在提问前我可以搜索一下,看看是否有人遇到同样问题?

谢谢大家!
...全文
2361 53 打赏 收藏 转发到动态 举报
写回复
用AI写文章
53 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
哦 我在楼上说错一个地方 一开始是进行“开始执行不调试”,这时是正常运行的;但若进行“调试(F5)”,则就出现楼上的图中的错误提示了。 另外,随着我这两天掌握更多的知识,我发现34楼这个新程序应该是存在问题的,即使它“开始执行不调试”是正常的。因为主窗体里的标签控件是一个私有类型的成员,按理说是不能在嵌套类里通过创建主窗体的实例对象来使用的,然而我的程序竟然就是通过创建对象来操作标签内容的,这恐怕存在问题。
  • 打赏
  • 举报
回复
见鬼啦 本来我以为我在34楼改的程序没问题了呢,用“开始调试不执行”是可以正常运行的,没有任何错误提示。然而我刚才使用“调试”(F5),却出现异常,无法调试下去! 真是郁闷啊! 我把截图给大家看看:
  • 打赏
  • 举报
回复
java中如何将字母转换成Unicode编码 谢谢
super_admi 2019-06-02
  • 打赏
  • 举报
回复
其实,那句提示已经很说明问题了。为什么不能使用外部类的非静态成员?就是因为你使用的时候,并不知道外部类的实例化对象是什么,而静态成员则没有这个问题,故可以使用。

所以,按此思路,解决这个问题,就有两个途径:
1.使用外部类的非静态成员时,传给内部类一个对象实例;

2.使用接口之类的方法,来完成你要做的事情。

总的来说,就一句话:你要有对象实例,才能使用非静态成员(类本身可以使用,是因为有默认的this)。
weixin_45169533 2019-06-02
  • 打赏
  • 举报
回复
分享内容:推荐大家一个靠谱的论文检测平台。重复的部分有详细出处以及具体修改意见,能直接在文章上做修改,全部改完一键下载就搞定了。怕麻烦的话,还能用它自带的降重功能。哦对了,他们现在正在做毕业季活动, 赠送很多免费字数,可以说是十分划算了!地址是:http://www.paperpass.com/
耐斯~ 2019-06-02
  • 打赏
  • 举报
回复
原来是酱紫的鸭
  • 打赏
  • 举报
回复
请看看你楼下我新改的程序,并没有用委托和Invoke啊,仅仅是正确地创建了外部类(也就是主窗体)的实例就行了,原先没正确地创建主窗体实例。
引用 33 楼 qq_23376991 的回复:
线程里请用委托。
  • 打赏
  • 举报
回复
哈哈哈,我参考@OrdinaryCoder(我也不知道如何在论坛里呼唤某人)的程序,在我原程序的基础上略加修改,仅仅是将主窗体的实例语句从构造函数里挪出来,单独写个方法SetForm,然后在主窗体里调用这个方法(我原程序没调用此方法,所以实际上并没有创建实例),就行了,其它的好像没改,大家可以对照一下3楼的原程序。也没有用到Invoke和委托。但是运行正常啊,而且不崩溃。这是怎么回事?我把新程序贴出来。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;     

namespace StudentInfoMS
{
    public partial class thread_2 : Form
    {
        myThread myThread1, myThread2;

        public thread_2()
        {
            InitializeComponent();
            myThread1=new myThread(100,progressBar1); 
            myThread1.SetForm(this);//这是新加的语句
            myThread2=new myThread(200,progressBar2); 
            myThread2.SetForm(this);//这是新加的语句
        }
         
        public class myThread       //创建一个线程的类 以便相似的进程都能调用它
        {
            private thread_2 text;      //这里是为了解决“嵌套类里不能使用外部类的非静态成员”而按照网上方法声明的一个外部类的实例  我也不知道正确否 
            private int SleepTime; 
            private ProgressBar progressBar; 
            private Thread thread1; 
            public myThread(int Time,ProgressBar p1) 
            { 
                SleepTime=Time; 
                progressBar=p1; 
                thread1=new Thread(new ThreadStart(fun)); 
                thread1.Start();
            }
            public void SetForm(thread_2 pp)//这是新加的语句
            {
                this.text= pp;//原先我把这句写到了窗体的构造函数里,可是我又不会调用构造函数,所以相当于白写这句了。现在是写到了方法里,然后在外部类里调用此方法。好像我就差在这儿了!否则早应该成功了!对照3楼的原程序,实际上整个程序我现在改动得非常少!
            }
            public void fun() 
            { 
                while(progressBar.Value!=100) 
                { 
                    progressBar.Value+=5; 
                    Thread.Sleep(SleepTime); 
                }              
                if (this.text.label1.Text == "")
                    this.text.label1.Text = "第一个线程结束";                 
                else
                    this.text.label1.Text += ",第二个线程结束";

                if (thread1.IsAlive)
                    thread1.Abort();
            } 
        }
    }
}
[quote=引用 31 楼 OrdinaryCoder 的回复:] [quote=引用 30 楼 weixin_45121425 的回复:] 我基本看懂你的程序和文字解释了:想在内部类里刷新外围类的成员,必须在内部类里创建外围类的实例。你是通过内部类的set方法及在外部类里调用这个方法来创建实例的。这个我理解了。然而有了这个实例this.mainFrom,为啥不能直接写this.mainFrom.textBox1.Text=某字符串?而是通过this.mainFrom.BeginInvoke(new RefreshEventHandle(ShowText));这样的委托来实现呢?不是都有实例了吗? textBox1.Text不就是实例的成员吗? 顺便说一句,我看好多人都会用到Invoke,而我学的那个教程里居然通篇没有这个关键字,愁人,我学的是哪个年代的教程啊? [quote=引用 26 楼 OrdinaryCoder 的回复:] [quote=引用 23 楼 正怒月神 的回复:] [quote=引用 2 楼 eaqpi 的回复:]
qq_23376991 2019-06-01
  • 打赏
  • 举报
回复
线程里请用委托。
  • 打赏
  • 举报
回复
我原先的错误是:虽然知道要建立外部类的实例,并且也在内部类的构造函数里写了相关语句,但却不知道如何重载它(内部类已经有一个包含2个参数的构造函数了),所以实际上没成功创建外部类实例,自然就引起后续错误。现在参考网友程序,摒弃构造函数方式,单独写个方法,在外部类里调用之,就成功创建实例了,一切都OK了。 我现在的问题有2个:1、假如继续用构造函数的方式,如何重载它?2、我现在没用委托和Invoke,也达到目的了。但为啥此贴里的人们都用Invoke呢?3、Java更适合嵌入式?我以为它主要是用于建网站呢。不过据说Java的语法跟C很接近,学起来应该相对容易吧?我搞嵌入式自然对C比较熟悉。 [quote=引用 36 楼 liuyu369 的回复:]
importsys 2019-06-01
  • 打赏
  • 举报
回复
楼上回答的很清楚了txtx
大焖锅 2019-06-01
  • 打赏
  • 举报
回复
引用 37 楼 liuyu369的回复:
[quote=引用 36 楼 liuyu369的回复:]首先建议好好补一下构造函数那部分,看代码是直接把人家的修改粘过来的。 修改的思路是在嵌套类里新建一个你要引用的外部类的数据类型再重载嵌套类构造函数给其赋值,在实例化嵌套类时把要引用的外部类的字段传进去就行。 不过话说回来既然不能调用非静态字段,干嘛不试试声明成静态字段
根据你描述的错误提示很可能是因为非静态字段要实例化后才分配内存,你直接在嵌套类里调用编译器无法判断外部类是否实例化了,然后就报错了[/quote] 对了,c#并不适合嵌入式要不换Java试试 否则等发现被吹上天的vscode连个32位机调试都不支持,换vs各种崩溃加上"未指定的错误未指定的引用"这种连个错误代码都不给的纯属找骂型的调试信息时,怕就已经悔之晚矣
大焖锅 2019-06-01
  • 打赏
  • 举报
回复
引用 36 楼 liuyu369的回复:
首先建议好好补一下构造函数那部分,看代码是直接把人家的修改粘过来的。 修改的思路是在嵌套类里新建一个你要引用的外部类的数据类型再重载嵌套类构造函数给其赋值,在实例化嵌套类时把要引用的外部类的字段传进去就行。 不过话说回来既然不能调用非静态字段,干嘛不试试声明成静态字段
根据你描述的错误提示很可能是因为非静态字段要实例化后才分配内存,你直接在嵌套类里调用编译器无法判断外部类是否实例化了,然后就报错了
大焖锅 2019-06-01
  • 打赏
  • 举报
回复
首先建议好好补一下构造函数那部分,看代码是直接把人家的修改粘过来的。 修改的思路是在嵌套类里新建一个你要引用的外部类的数据类型再重载嵌套类构造函数给其赋值,在实例化嵌套类时把要引用的外部类的字段传进去就行。 不过话说回来既然不能调用非静态字段,干嘛不试试声明成静态字段
weixin_45165273 2019-06-01
  • 打赏
  • 举报
回复
libsvm数据格式老出错,请问有没有靠谱教程
大焖锅 2019-06-01
  • 打赏
  • 举报
回复
1.invoke,委托算消息响应方面的内容属于设计模式那个层次,解决的是你有成百上千个模块类时数据交互的问题主要为了解耦依赖以及保证数据安全,你这个练习主要考察小范围内的语法应用,牛刀可以杀鸡,但开销太大 2.我看到源代码里的注释觉得你不太懂怎么用构造函数所以建议多去看看这部分 具体的要是我遇到这问题首先想到的是把你要调用的外部类字段声明为public static然后在嵌套类里类名加点调用(当然手里没net环境不知道能不能行,毕竟这里面也涉及些内存分配顺序问题) 然后构造函数调用大概是在外部类中new一个嵌套类传参不过不清楚你到底怎么调mythread类和嵌套类的的毕竟没给main入口 3.arm不太了解貌似比单片机还基础些,不过看到arm貌似有对Java进行过硬件加速貌似叫什么jazelle想来arm也怕微软突然崩了吧,这真不是危言耸听,当然arm我也不了解只给个思路,要是坑别赖我 4.关于用户界面设计这点小白确实容易误解其实现在编程语言对界面支持都不错毕竟都9012年了而且其实越高级的语言这越不是问题脚本语言了解下,耍起流氓来按键精灵和易语言了解下。当然Windows平台下net是有优势的,而且语法糖衣也不少入门容易点吧,但也有坏处像那个无返回值委托action没接触你想得到?即使学了你知道糖衣下的具体执行过程?要是哪天再跳个"未指定的错误"或者vs崩溃怕没处哭去,但跨平台方面net真是一言难尽,毕竟你不能保证生产环境中上位机永远都是Windows系统,都是win10环境,都是win1064位环境吧,何况如果你的下位机配置够也是可以装jvm然后上位机和下位机的运行结果就一致了。 最后扒扒微软的黑历史,遥想当年微软打算一统PC端不但不支持跨平台,各种接口还有意和其他操作系统对着干,直到Java出现连移动端都占了微软才开始跨平台可惜自己挖的坑还得自己填,各种接口搞得乱七八糟,实在不行只能以升级为接口废掉以前的mfc开发net,可以就不行又废了net2,net3,net4又大改api强推win10想统一接口导致一些用老框架写的项目没用几年就得重写,让无数程序员从此微软一生黑,话说你改好也凑合vs,net不仅重得要死还各种崩,那种"未指定的错误"是来搞笑的吗?所以c#死活进不了前五不是没道理的
暮云深处 2019-06-01
  • 打赏
  • 举报
回复
膜拜大佬操作
  • 打赏
  • 举报
回复
1、本帖里的其他人都用invoke和委托了,但我现在没用,也实现了目的,我想知道咋回事?2、同一个类里可以有好几个构造函数,只是参数不同,New哪个就执行哪个,这个我知道。我是不知道在我的程序里,应该在啥地方New我想New的那个构造函数。3、我主要搞以ARM为核心的软硬件,也想掌握一些上位机能力。这回学C#是因为据说它做上位机界面比较方便。但我也许以后不仅仅限于做个简单的与下位机通讯的界面。所以,你建议我学Java?4、通过这几天纠结,我发现嵌套类可能是用得不多,我是按照教程学的,就学到这一步。5、如何在帖子里@某人? [quote=引用 42 楼 liuyu369 的回复:]
大焖锅 2019-06-01
  • 打赏
  • 举报
回复
引用 42 楼 liuyu369的回复:
重载只是调用的一种方式,在new对象时把参数传进去,编译器会自动根据你实例时的对象选择一个与你格式相符的构造函数签名并自动调用它称为重载。不需要人为操作 像楼上提到过的你的问题本质上是两个类之间的数据传递那么消息响应机制就是最正统的处理方式所以有人推荐invoke和委托,但缺点是消息响应机制一般在大型项目中比较方便,像这种初级菜鸟程序怕会把你绕进去 关于嵌入式不知道你是搞微控制器的还是微处理器抑或是单片机的。不过c#和c的关系一点也不比Java和c的关系来的近,c是所有操作系统和编程语言的起点,所以旧但永不过时。Java和c#以及其他编程语言都是在c的基础上开发的,不要觉得名字里带个c就就跟c有多亲近。另外面向对象只有在处理复杂关系时好用,如果是微控或单片机c的面向过程反而更贴近单片机的工作流程。如果是微处理还是建议Java毕竟Java是基于虚拟机的很大程度上独立于操作系统,一开始就是靠跨平台起家。而微软是半路出家开始还抵制跨平台现在勉强搞了个netcore也是历史遗留问题无数很容易掉坑,最后毛衣战背景下Java可以说是受外国影响最小的开发环境了。
对了最后在给个忠告如果可以不用嵌套就别用嵌套能少套一层就少套一层,不管是类,循环,判断,指针还是别的啥的,以后做大型项目时会感谢这个习惯的。
大焖锅 2019-06-01
  • 打赏
  • 举报
回复
重载只是调用的一种方式,在new对象时把参数传进去,编译器会自动根据你实例时的对象选择一个与你格式相符的构造函数签名并自动调用它称为重载。不需要人为操作 像楼上提到过的你的问题本质上是两个类之间的数据传递那么消息响应机制就是最正统的处理方式所以有人推荐invoke和委托,但缺点是消息响应机制一般在大型项目中比较方便,像这种初级菜鸟程序怕会把你绕进去 关于嵌入式不知道你是搞微控制器的还是微处理器抑或是单片机的。不过c#和c的关系一点也不比Java和c的关系来的近,c是所有操作系统和编程语言的起点,所以旧但永不过时。Java和c#以及其他编程语言都是在c的基础上开发的,不要觉得名字里带个c就就跟c有多亲近。另外面向对象只有在处理复杂关系时好用,如果是微控或单片机c的面向过程反而更贴近单片机的工作流程。如果是微处理还是建议Java毕竟Java是基于虚拟机的很大程度上独立于操作系统,一开始就是靠跨平台起家。而微软是半路出家开始还抵制跨平台现在勉强搞了个netcore也是历史遗留问题无数很容易掉坑,最后毛衣战背景下Java可以说是受外国影响最小的开发环境了。
加载更多回复(33)
前导课程:      《Java工程师系列课程》前4部课程内容:       本课程是《Java工程师系列课程》的第7部分,主要讲解Java实际开发过程中常用类,特别是各种工具类的使用。熟练掌握这些类的使用方法,能够大幅度提高编程效率。同时还在课程中穿插讲解了很多Java语言的设计思想和理念,深刻理解并掌握这些编程思想能够从根本上提高编程水平和解决问题的能力。在课程的末尾还安排了国际化软件实战项目。       本课程涉及的主要内容如下表所示:课程说明:      在开发Java程序的过程中,无论做什么类型的项目,都会用到各种工具类来解决一些实际问题。这些工具类被广泛的应用与各种行业软件的开发。比如我们经常会用BigDecimal类来的完成浮点数的精确计算,也会用Formatter类完成文本、数字、日期的格式化操作等等。      为了能够让学员迅速掌握这些工具类的使用,我们特意开发了这门视频课程,视频中详细讲解了20余种常用工具类的使用规则。此外,在课程中,还讲解了很多Java语言的设计思想和理念,可以让学员在听课过程中能够对Java语言有更加深刻的理解和认识。      最后,本课程还安排了一个小型国际化软件的实战项目,通过实战让学员掌握国际化软件的开发理念和实际操作流程预期效果:      认真学习完本课程,学员可以掌握20种Java实战开发中常用类的使用方法,实实在在提高实战水平,完成从菜鸟到高手的华丽转变。配套福利:中英文双语版本自助购物软件的完整源码环境配置要求:      学习本课程需安装JDK13或更高版本的JDK,以便程序能正确运行,建议使用IntelliJ IDEA 2019.1.2或更高版本的开发工具。     因有合作协议约束,《穆哥学堂》只提供PDF版本的课件!

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧