首页 > 编程知识 正文

c上m下n公式,c代表什么

时间:2023-05-05 04:39:19 阅读:21923 作者:4033

转载:我经常听到朋友在讨论https://www.cn blogs.com/to-creat/p/5268729.html c#的结构和类差异。 正好这几天有空,请自己总结一下,告诉我。

1 .首先是语法定义上的差异啊。 这是不言而喻的。 使用关键字class定义类,使用关键字struct定义结构。 语法上其实有很多和类和结构相似的地方。

定义类的语法

1 class person2{ 3专用名称; 4私密int age; 5公共void sayhi (7{ 8控制台. writeline )、My Name is ' this.name )、My Age is ' this.age ); 9 }10 }

定义结构的语法。

1结构恢复2 { 3隐私窗口; 4个人隐私保护; 5公共int getarea (7(8return this.width * height; 9 }10 }

从语法上看.那些语法都大同小异,类内的成员几乎都可以定义为结构体,析构函数除外.为什么呢? 稍后解答。

2 .虽说语法非常相似,但语法有一些区别。

a.在结构体中可以声明字段,但是声明字段的时候是不能给初始值的.,因此,当您尝试以这种方式编写代码时,C#编译器将源代码编译到程序集中会提示语法错误。

已知如果在类中声明一个字段,同时为该字段指定初始值,则可以按如下方式滴加:

class person { privatestring name=' jack '; }但是,不能这样做。 声明一个字段后,为此字段赋值,如下所示:

1 class person2{ 3专用名称; 4 name='jack '; 5 }

所以说类下面只能直接定义类的成员,只能定义。 例如,定义成员字段、属性方法构造函数等。 类似以上代码name='jack '的代码我们称为“执行代码”。 这意味着这些代码只有在运行时才有效。 那么,请想想这些代码什么时候运行。 当创建类的对象时? 那个还需要构造函数吗? 我经常看到在班级下面直接写这样代码的初学者。

但是还有人要说.诶,那么为什么在声明类的字段时可以赋值呢? 赋值表达式也是一个执行代码吗? 为什么不就此报告错误呢? 请给我看一下代码。 我知道那个真相。

使用C#编译器将此代码编译到程序集时,让我们看看微软为我们生成的代码。

展开构造函数,看看这里面有什么奇怪的地方。

是的,如果C#编译器在编译时、声明字段时为字段赋值,则为字段赋值的代码C#编译器会在构造函数中包含编译时赋值的代码。 其实严格意义上说,类的字段也不能有初始值。 微软只是在背后帮我做了点什么,我们只是不知道。

因此,无论是类还是结构,执行代码都必须写在方法中。 不能直接写在结构或班级的下面。 在将执行代码写入方法时,只有在调用该方法时才能确定这些执行代码的执行时间。

综上所述,实际上,类和结构字段不能有初始值。 但是,微软在语法上允许在定义类的字段时赋值。 但是,在背后微软实际上是将赋值的执行代码放入构造函数中执行的。 结构体微软不会为我做那个。 至于原因,查了一些资料,看了院子里其他博友的文章,感觉也说不过去。

b. 关于构造函数.

首先,关于隐式构造函数。 我们知道,如果不在一个类中编写任何构造函数,C#编译器将在编译时自动生成没有该类参数的构造函数。 此构造函数称为隐式构造函数,但当您为此类编写任意一个构造函数时,不会自动生成此隐式构造函数。

在结构上则不然.在结构上无论如何都存在隐式构造函数.请看代码.

下面的代码编写了一个结构带参数的构造函数。如下所示。

  我们使用new关键字来创建结构体对象,我们发现调用构造函数的时候,提示是有两个构造函数的.多了1个无参数的构造函数.

     

   那么 我们再想,能不能手动的写1个无参数的构造函数呢?我们怀着无比激动的心情,试一下.

   

  结果是华丽丽的报错了.所以我们得出结论. 隐式的无参数的构造函数在结构中无论如何都是存在的,所以程序员不能手动的为结构添加1个无参数的构造函数.

  关于构造函数当然还不仅仅如此.我们知道在类的构造函数中我们可以写一些任意的代码(前提是符合C#语法啦),在结构体的构造函数中虽然也可以写任意的代码.但是C#语法规定在结构体的构造函数中,必须要为结构体的所有字段赋值.看看下面的代码吧.

   

   啊哦.....报错了.....

   我们也知道,在结构中还可以定义属性,所以有童鞋就这样写啦.看下面代码.

   

   这个错误,仍然提示我们在构造函数中没有为所有的字段赋值,这是很多童鞋遇到的问题,诶,不是要在构造函数中为所有的字段赋值么?我现在赋值了啊。为什么还是提示没有赋值呢? 我们在构造函数中为属性赋值 而属性又为字段赋值,为什么这样就不行呢? 原因很简单.因为语法要求我们为所有的字段赋值,虽然这里我们看得出来为属性赋值其实属性再把值赋值给字段, 我们说属性是对字段的操作,但是一定是这样的吗?我们完全可以在属性的set块里面什么都不写,如果什么都不写,那么属性还是在操作字段吗? 所以属性不一定是在操作字段的,在结构体的构造函数中我们为属性赋值,不认为是在对字段赋值,所以我们在构造函数中要直接为字段赋值.

  c.创建结构体对象的方式.

   创建结构体对象可以不使用new关键字.直接声明1个变量就可以.但是这样的话,结构体对象中的字段是没有初始值的,所以在使用字段之前必须要为这个字段赋值.

   

   原因很简单.因为声明的时候就不能给初始值,虽然构造函数中为对象的字段赋值,但是此种方式创建结构体对象,没有调用构造函数,所以必须要程序员在使用之前手动赋值。下面这样就可以了.

   

  另外1种创建结构体对象的方式和类一样,使用new关键字来创建,与不使用new关键字创建不同的是,通过使用new关键字创建结构体对象后,这个结构体对象的字段就已经有值了.原因不难理解,new关键字调用了构造函数,而结构体构造函数要求必须要为所有的字段赋值.

  

  所以,我们不难猜出.结构体的无参数的构造函数做了什么事情,在无参数的构造函数中为所有的字段赋值,值类型的字段赋值0,给引用类型的字段赋值null.

  d. 结构体不能从另外1个结构或者类继承,但是可以实现接口.特殊的是.虽然结构不能从别的类或者结构继承,但是所有的结构都默认从ValueType类继承,ValueType类再从Object类继承.所以结构体对象仍然拥有超类Object的成员.看看下面的微软生成的代码就知道了.

    

3. 它们之间最大的区别 是结构体是值类型 类是引用类型.

   结构体是值类型,当其作为1个局部变量的时候,变量是存储在栈空间中的,其对象的字段直接存储在这个变量中的.就像下面这样.

   

   与引用类型的类不一样,引用类型的变量中存储的是对象在堆空间中的地址,所以当我们传递1个引用类型的变量的时候,其实传递的是变量的值(对象的地址) 传递完以后 对变量的修改会影响到另外1个变量指向的对象的值.

 

4. 最后 谈一下什么时候使用结构,什么使用类.

   我们知道,结构存储在栈中,而栈有1个特点,就是空间较小,但是访问速度较快,堆空间较大,但是访问速度相对较慢.所以当我们描述1个轻量级对象的时候,可以将其定义为结构来提高效率.比如点,矩形,颜色,这些对象是轻量级的对象,因为描述他们,只需要少量的字段。当描述1个重量级对象的时候,我们知道类的对象是存储在堆空间中的,我们就将重量级对象定义为类. 他们都表示可以包含数据成员和函数成员的数据结构。与类不同的是,结构是值类型并且不需要堆分配。结构类型的变量直接包含结构的数据,而类类型的变量包含对数据的引用(该变量称为对象)。 struct 类型适合表示如点、矩形和颜色这样的轻量对象。尽管可能将一个点表示为类,但结构在某些方案中更有效。在一些情况下,结构的成本较低。例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。所以结构适合表示1个轻量级对象.

   基于另外1个理由我也会使用结构. 我们在变量传值的时候,我就是希望传递对象的拷贝,而不是对象的引用地址,那么这个时候也可以使用结构了.

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。