C#是微软公司设计的一种编程语言,是从C和C++派生来的一种简单、现代、面向对象和类型安全的编程语言,并且能够与.NET框架完美结合。C#具有一下突出的特点:
(1)、语法简洁。不允许直接操作内存,去掉了指针操作。
(2)、彻底的面向对象设计。C#具有面向对象语言所应有的一切特性:封装、继承、多态。
(3)、与Web紧密结合。C#支持绝大多数的Web标准,例如HTML、XML、SOAP等。
(4)、强大的安全性机制。可以消除软件开发中常见的错误(如语法错误),.NET提供的垃圾回收器能够帮助开发者有效地管理内存资源。
(5)、兼容性。因为C#遵循.NET的公共语言规范(CLS),从而保证能够与其他语言开发的组件兼容。
(6)、灵活的版本处理技术。因为C#语言本身内置了版本控制功能,使开发人员更加容易地开发和维护。
(7)、完善错误、异常处理机制。C#提供了完善的错误和异常处理机制,使程序在交付应用时能够更加健壮。
.NET Framework是微软公司推出的全面面向对象的软件开发与运行平台。.NET Framework具有两个主要组件:公共语言运行时(Common Language Runtime,CLR)和类库。
公共语言运行时:公共语言运行时(CLR)负责管理和执行由.NET编译器编译产生的中间语言代码(.NET程序执行原理如图1.1所示)。由于公共语言运行库的存在,解决了很多传统编译语言的一些致命缺点,如垃圾内存回收、安全性检查等。
类库:类库我们比较好理解,就好比一个大仓库里面装满了工具。类库里有很多现成的类,可以拿来直接使用。例如,文件操作时,可以直接使用类库里面的IO类。
.NET框架是微软公司推出的一个全新的编程平台,目前的版本是4.7。C#是专门为与微软公司的.NET Framework一起使用而设计的(.NET Framework是一个功能非常丰富的平台,可开发、部署和执行分布式应用程序)。C#就其本身而言只是一种语言,尽管它是用于生成面向.NET环境的代码,但它本身不是.NET的一部分。.NET支持的一些特性,C#并不支持。而C#支持的另一些特性,.NET也支持(例如运算符重载)。在安装Visual Studio 2017的同时,.NET Framework 4.7也被安装到本地计算机中。
在当前的主流开发语言中,C/C++一般用于在底层与桌面程序;PHP等一般只是用在Web开发上;而只有C#,它几乎可用于所有领域,如嵌入式、便捷式计算机、电视、电话、手机和其他大量设备上运行。C#的用途数不胜数,它拥有无可比拟的能力。C#的应用领域只要包括:
游戏软件开发
桌面应用系统开发
交互式系统开发
智能手机程序开发
多媒体系统开发
网络系统开发
RIA应用程序(Silverlight)开发
操作系统平台开发
WEB应用开发
参考博客
:https://blog.csdn.net/Camel_Wang/article/details/78696606
(1)、在Windows操作系统的"开始"菜单界面中找到Visual Studio 2017,单击打开。
(2)、选择Visual Studio 2017工具栏中的"文件"->“新建”->“项目"命令,打开"新建项目"对话框。
(3)、选择 控制台应用(.NET Framework) Visual C# 选项,命名为"Hello_World”,选择保存路径,然后单击"确认"按钮创建一个控制台应用程序。
(4)、在Main()方法中输入代码。
命名空间:C#程序是利用命名空间组织起来的。命名空间即用作程序的"内部"组织系统,也用作向"外部"公开的组织系统(即一种向其他程序公开自己拥有的程序元素的方法)。如果要调用某个命名空间中的类或方法,首先需要使用using指令引入命名空间,using指令将命名空间名所标识的命名空间内的类型成员导入当前编译单元中,从而可以直接使用每个被导入的类型的标识符,而不必加上它们的完全限定名。
using指令的基本形式为: using 命名空间名;
类:类是一种数据结构,它可以封装数据成员、函数成员和其他的类。类是创建对象的模板。C#中的所有语句都必须位于类内。因此,类是C#语言的核心和基本构成模块。C#支持自定义类,使用C#编程就是编写自己的类来描述实际解决的问题。
类的声明形式为: [类修饰符] class [类名] [基类或接口](可省略){ 类体 }
Main()方法:Main()方法是程序的入口点,C#程序中必须包含一个Main()方法,在该方法中可以创建对象和调用其他方法,在一个C#程序中只能有一个Main()方法,并且在C#中所有的Main()方法都必须是静态的。C#是一种面向对象的编程语言,它即是程序的启动入口点,也是一个类的成员。由于程序在启动时还没有创建类的对象,因此,必须将入口点Main()方法定义为静态方法,使它可以不依赖于类的实例对象而执行。
Main()可有三个修饰符修饰,分别是public、static和void。
public: 说明Main()方法是共有的,在类的外面也可以调用整个方法。
static: 说明Main()方法是一个静态方法,即这个方法属于类的本身而不是这个类的特定对象。调用静态方法不能使用类的实例化对象,必须直接使用类名来调用。
void: 说明Main()方法无返回值。
标识符:C#语言规定标识符由任意顺序的字母、下划线、和数字组成,并且第一个字符不能是数字。标识符不能是C#中的保留关键字。
关键字:关键字是C#语言中已经被赋予特定意义的一些单词,不可以把这些关键字作为标识符来使用。C#语言中的常用关键字如下表:
C#语句:语句是构成C#的基本单位。语句可以声明局部变量或常数、调用方法、创建对象或将值赋给变量、属性、字段,语句通常以分号终止。
注释:编译器在编译程序时不执行注释的代码或文字,其主要功能是对某行或某段代码进行说明,方便对代码的理解与维护。
注释方式1:
代码书写规则:
(1)、尽量使用接口,然后使用类实现接口,以提高程序的灵活性。
(2)、尽量不要手工更改计算机生成的代码,若必须更改,一定要改成和计算机生成的代码风格一样。
(3)、关键的语句(包含声明关键的变量)必须要写注释。
(4)、建议局部变量在最接近使用它的地方声明。
(5)、不要使用goto系列语句,除非是用在跳出深层循环时。
(6)、避免写超过5个参数的方法。如果要传递多个参数,则使用结构。
(7)、避免书写代码量过大的try-catch代码块。
(8)、避免在同一个文件中放置多个类。
(9)、生成或构建一个长的字符串时,一定要使用StringBuilder类型,而不用string类型。
(10)、switch语句一定要有default语句来处理意外情况。
(11)、对于if语句,应该使用一对"{}"把语句块包含起来。
(12)、尽量不使用this关键字引用。
命名规范:
(1)、用Pascal规则来命名方法和类型,Pascal的命名规则是第一个字母必须大写,并且后面的连词的第一个字母均为大写。例如:UserId, UserName等。
(2)、用Camel规则来命名局部变量和方法的参数,Camel规则是指名称中第一个单词的第一个字母小写,并且后面的连接词的第一个字母均为大写。例如:userId, userName等。
(3)、所有的成员变量前加前缀"_“(非必须)。例如: private string _connectionString;
(4)、接口的名称加前缀"I”(非必须)。例如:public interface Iconvertible {};
(5)、方法的命名,一般将其命名为动宾短语。例如:createFile, getPath等。
(6)、所有的成员变量声明在类的顶端,用一个换行把它和方法分开。
(7)、用有意义的名字命名空间namespace。例如 namespace 公司名/项目名 {}。
(8)、使用某个控件的值时,尽量命名局部变量。
变量本身用来被存储特定类型的数据,可以根据需要随时改变变量中所存储的数据值。变量具有名称、类型和值。变量名是变量在程序源代码中的标识。变量类型确定它所代表的内存的大小和类型,变量值是它所代表的内存块中的数据。在程序的执行过程中,变量的值可以发生变化。使用变量之前必须先声明变量。即指定变量的类型和名称。
声明变量:声明变量就是指定变量的名称和类型。变量的声明非常重要,未经声明的变量并不合法,也因此没有办法在程序中使用。在C#中,声明一个变量是由一个类型和跟在后面的一个或多个变量名组成的,多个变量之间用逗号分开,声明变量以分号结束。
注意:
(1)、变量名只能由数字、字母和下划线组成。
(2)、变量名的第一个字符只能是字母和下划线,不能是数字
(3)、不能使用关键字作为变量名。
(4)、一旦一个语句块中定义了一个变量名,那么在变量的作用域内都不能在定义同名的变量。
(5)、C#语言允许汉字或其他语言文字作为变量名,但建议尽量不要使用这些语言文字作为变量名出现在程序中,影响程序的可读性。
变量的赋值:在C#中,使用赋值运算符"="来给变量赋值,将等号右边的值赋值给左边的变量。
注意:
(1)、在对多个同类型的变量赋同一个值时,为了节省代码的行数,可以同时对多个变量进行初始化。例如 int a, b, c, d; a = b = c = d = 10;
变量的作用域:由于变量被定义出来后只是暂存在内存中,等到程序执行到某一个点后,该变量就会被释放掉,也就是说变量有它的生命周期。因此,变量的作用域是指程序代码能够访问该变量的区域,若超出该区域,则在编译时会出现错误。
注意:
(1)、在类体中定义的变量被称为成员变量,成员变量在整个类中都有效。类的成员变量又可以分为两种,即静态变量和实例变量。
(2)、在类的方法体中定义的变量为局部变量。
值类型:值类型变量直接存储其数据值,主要包含整数类型,浮点数类型以及布尔类型等。值类型变量在栈中进行分配,因此效率很高,使用值类型的目的主要是为了提高性能。值类型具有如下特性:
(1)、值类型变量都存储在栈中。
(2)、访问值类型变量时,一般都是直接访问其实例。
(3)、每个值类型变量都有自己的数据副本,因此对一个值类型变量的操作不会影响其他变量。
(4)、复制值类型变量时,复制的是变量的值,而不是变量的地址。
(5)、值类型变量不能为null,必须具有一个确定的值。
注意:
(1)、整形数据在C#程序中有3种表示形式,分别为十进制、八进制和十六进制。不能以0作为十进制的开头(0除外),八进制必须以0开头,十六进制必须以0X或0x开头。
(2)、若果需要使用float类型变量时,必须在数值的后面跟随f或F,否则编译器会直接将其作为double类型处理。也可以在double类型的值前面加上(float),对其进行强制转换。
(3)、布尔类型主要用来表示true和false值,一个布尔类型的变量,其值只能是true或者false,不能将其他值指定给布尔类型变量,布尔类型变量不能与其他类型之间进行转换。
引用类型:引用类型是构建C#应用程序的主要对象类型数据。在应用程序执行过程中,预先定义的对象类型以new创建对象实例,并且存储在堆中。堆是一种有系统弹性配置的内存空间,没有特定大小及存活时间,因此可以被弹性地运用于对象的访问。引用类型就类似于生活中的代理商,代理商没有自己的产品,而是代理厂家的产品。引用类型具有如下特征:
(1)、必须在托管堆中为引用分配内存。
(2)、使用new关键字来创建引用类型变量。
(3)、在托管堆中分配的每个对象都有与之相关联的附加成员,这些成员必须被初始化。
(4)、引用类型变量是由垃圾回收机制来管理的。
(5)、多个引用类型变量可以引用同一个对象,这种情形下,对一个变量的操作会影响另一个变量所引用的同一个对象。
(6)、引用类型被赋值前的值都是null。
注意:
C#的所有值类型均隐式派生自System.ValueType,而System.ValueType直接派生与System.Object。即System.ValueType本身是一个类类型,而不是值类型。其关键在于ValueType重写了Equals()方法,从而对值类型按照实例的值来比较,而不是引用地址来比较。
值类型与引用类型区别:
枚举类型:枚举类型是一种独特的值类型,它用于声明一组具有相同性质的常量,编写与日期相关的应用程序时,经常需要使用年、月、日、星期等日期数据,可以将这些数据组织成多个不同名称的枚举类型,使用枚举可以增加程序的可读性和可维护性。同时,枚举类型可以避免类型错误。实例如下:
类型转化:类型转换就是将一种类型转换成另一种类型,常规转换方式是隐式转换和显示转换,特殊的转换方式为装箱和拆箱。隐式转换:就是不需要声明就能进行的转换。显式转化:可以被称为强制转换,需要在代码中明确地声明要转换的类型,显示转换可能导致精度损失。装箱:将值类型数据转换为引用类型数据的过程叫装箱。拆箱:将引用类型转换为值类型的过程叫做拆箱。
注意:
装箱是一个值类型转换为一个对象类型(object),而拆箱则是将一个对象类型显示转换为一个值类型。对于装箱而言,它是将被装箱的值类型复制一个副本来转换;而对于拆箱而言,需要注意类型的兼容性,例如,不能将一个值为"string"的object类型转换为int类型。实例如下:
常量就是其值为固定不变的量,而且常量的值在编译时已经确定了。在C#中常量分为静态常量(const)和动态常量(readonly),并且在创建常量是必须设置它的初始值。对于const与readonly的区别可参考以下博客学习:
https://www.cnblogs.com/yanglang/p/9003770.html
表达式是由运算符和操作数组成的。+、-、*和/等都是运算符,操作数包括文本、常量、变量和表达式等。在C#中,如果表达式最终的计算结果为所需的类型值,表达式就可以出现在需要值或对象的任意位置。
算术运算符:‘+’,‘-’, ‘*’,‘/’和‘%’运算符都称为算术运算符,分别用于加、减、乘、除和模(求余)运算。其中,‘+’和‘-’运算符还可以作为数据的正负符号。
注意:
(1)、如果想要对整型变量num进行加1操作,可以用"num = num + 1"来实现,也可以用增量运算符(++)实现。如num++或++num。++num是前缀增量操作,该操作的结果是操作符加1之后的值;num++是后缀增量操作,该运算的结果是操作数增加之前的值。例如:int num = 1,若b = num++, 打印b的值为1,若b = ++num,打印b的值为2。
(2)、如果想要对整型变量num进行减1操作,可以用"num = num - 1"来实现,也可以用减量运算符(--)实现。如num--或--num。--num是前缀减量操作,该操作的结果是操作符减去1之后的值;num--是后缀减量操作,该运算的结果是操作数减去之前的值。例如:int num = 1,若b = num--, 打印b的值为1,若b = --num,打印b的值为0。
(3)、除法运算时,若两边都为整数,则计算的商为整数,即使两边不能整除,最终的结果也只保留整数位。
(4)、在获取两个数相除的余数时,也可以用Math类的DivRem()方法来实现,如上述代码中的result = num1 % num2可以写成Math.DivRem(num1,num2),result中存储了num1和num2的余数。
赋值运算符:赋值运算符为变量、属性、事件等元素赋新值。赋值运算符主要有:‘=’ ‘+=’ ‘-=’ ‘*=’ ‘/=’ ‘%=’ ‘&=’ ‘|=’ ‘^=’ ‘<<=’ 和 ‘>>=’运算符。赋值运算符的左操作数必须是变量、属性访问、索引器访问或事件访问类型的表达式,如果赋值运算符两边的操作数的类型不一致,就需要首先进行类型转换,然后在赋值。
注意:
(1)、在使用赋值运算符时,右操作数表达式所属的类型必须可隐式转换为左操作数所属的类型,运算将右操作数的值赋给左操作数指定的变量、属性或索引器元素。
关系运算符:关系运算符属于二元运算符,用于程序中的变量之间、变量与自变量之间以及其他类型的信息之间的比较,它返回一个代表运算结果的布尔值。当运算符对应的关系成立时,运算结果为true,否则为false。
逻辑运算符:返回类型为布尔值的表达式,如关系运算符,可以被组合在一起构成一个更复杂的表达式,这是通过逻辑运算符来实现的。C#中的逻辑运算符主要包括“&(&&)(逻辑与)” “||(逻辑或)” “!(逻辑非)”。逻辑运算符的操作元必须是bool型数据。在逻辑运算符中,除了“!”是一元运算符之外,其它的都是二元运算符。
位运算符:位运算符除按位与,按位或运算符外,其他只能用于处理整数的操作数。位运算是完全针对位方面的操作。
注意:
(1)、移位可以实现整数除以或乘以2的n次方的效果。例如,y << 2与 y * 4 的结果相同;y >> 1的结果与y / 2 的结果相同。总之,一个数左移n位,就是将这个数乘以2的n次方;一个数右移n位,就是将这个数除以2的n次方。
其他特殊运算法:C#中还有一些不能简单的归到某个类型中,如is运算符,条件运算符,new运算符,typeof运算符等。
注意:
(1)、不能重载is运算符。is运算符只考虑引用转换、装箱转换和取消装箱转换。不考虑其他转换,如用于定义的转换。
C#中的表达式是使用运算符连接起来的符合c#规范的式子,运算符的优先级决定了表达式中运算符的先后顺序。通常优先级由高到低的顺序依次为:增量和减量运算符—>算术运算符—>关系运算符—>逻辑运算符—>赋值运算符。
所有运算符从高到低的优先级顺序如下:
简称 | 运算符 |
---|---|
基本 | x.y,f(x),a[x],x++,x–,new,typeof,checked,unchecked |
一元 | +,-,!,++x,–x,new,T(x) |
乘除 | *,/,% |
加减 | +,- |
位移 | <<,>> |
比较 | >,<,<=, >=,is,as |
相等 | ==,!= |
位与 | & |
位异或 | ^ |
位或 | | |
逻辑与 | && |
逻辑或 | | | |
条件 | ? : |
赋值 | =,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>= |
char类主要用来存储单个字符,占用16位(两个字节)的内存空间。
Char的使用:
注意:
(1)、Char只定义了一个Unicode字符。Unicode字符是目前计算机中通用的字符编码,它为针对不同语言中的每个字符设定了统一的二进制编码,用于满足跨语言,跨平台的文本转换、处理的要求。
(2)、Char类为开发人员提供了许多方法,可以通过这些方法灵活地操作字符。
注意:
(1)、转义符“\”(单个反斜杠)只针对后面紧跟着的单个字符进行操作。
(2)、大多数重要的正则表达式语言运算符都是非转义的单个字符。转义符“\”(单个反斜杠)通知正则表达式分析器反斜杠后面的字符不是字符。例如,分析器将r视为字符,而将后跟r的反斜杠(\r)视为按Enter键功能。
由多个字符连接而成的字符串,在C#语言中字符串作为对象来处理,可以通过String类来创建字符串对象。
字符串的声明及赋值:
注意:
(1)、声明字符串变量必须经过初始化才能使用,否则编译器会报出“使用了未赋值的变量”。
(2)、C#中一句相连的字符串不能分开在两行中写。如果一个字符串太长,为了便于阅读,可以将这个字符串分在两行书写。此时就可以试用“+”将两个字符串连起来,之后在加号后换行。
比较字符串:
注意:
(1)、比较字符串并非比较字符串长度的大小,而是比较字符串在英文字典中的位置。比较字符串按照字典排序规则,判断两个字符串的大小。在英文字典中,前面的单词小于在后面的单词。
格式化字符串:
注意:
(1)、在用Substring()方法截取字符串时,如果length参数的长度大于截取字符串的长度,将从起始位置的索引处截取之后的所有字符。
分割字符串:
注意:
(1)、参数count的值不能为0或者负数(startIndex参数也不能为负数),如果为负数,将会引发ArgumentOutOfRangeException异常(当参数值超出调用的方法所定义的允许取值范围时引发的异常);如果为0,则删除无意义,也就是没有进行删除。
复制字符串:
注意:
(1)、当参数sourceIndex、destinationIndex或count为负数,或者参数count大于从startIndex到此实例末尾的字符串的长度,或者参数count大于从destinationIndex到destination末尾的子数组的长度时,则引发ArgumentOutOfRangeException异常(当参数值超出调用的方法所定义的允许取值范围时引发的异常)。
替换字符串:
对于创建成功的字符串String类,它的长度是固定的,内容不能被改变和编译。虽然使用“+”可以达到附加新字符或字符串的目的,但“+”会产生一个新的String实例,会在内存中创建新的字符串对象。如果重复地对字符串进行修改,将极大地增加系统开销。而C#中提供了一个可变的字符序列StringBuilder类。大大提高了频繁增加字符串的效率。
String对象是不可改变的,每次使用String类中的方法时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的String对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用StringBuilder类。
注意:
(1)、虽然if后面的语句序列块只有一条语句,可以省略“{ }”并无语法错误,但为了增强程序的可读性最好不要省略。
(2)、对于if……else语句可以使用三元条件运算符(? :)对语句进行简化。
(3)、在if语句中可以使用return语句,用于退出if语句所在的类的方法。
(4)、switch语句可以包含任意数目的case子句,但是任何两个case语句都不能具有相同的值。
(5)、在switch语句中,case语句后常量表达式可以为整数,但绝不可以为实数。
注意:
(1)、在循环语句中,可以通过goto、return或throw语句退出。
注意:
(1)、在循环体中,不要在同一个语句块中使用多个跳转语句。
(2)、goto的一个通常用法是将控制传递给特定的switch……case标签或switch语句中的默认标签。goto语句还有于跳出深层嵌循环。
注意:
(1)、使用new关键字为数组分配内存时,整型数组中各个元素的初始值都为0。
注意:
(1)、在Sort()方法中所用到的数组不能为空,也不能是多维数组,它只对一维数组进行排序。
ArrayList类位于System.Collections命名空间下,它可以动态的添加和删除元素。与数组相比:ArrayList容量可以根据需要自动扩充,而数组的容量则是固定的;ArrayList提供添加、删除和插入某一范围元素的方法,但在数组中,只能获取或设置一个元素的值;ArryaList提供将只读和固定大小包装返回集合的方法,而数组不提供;但ArrayList只能是一维形式,而数组可以是多维的。
常用属性 | 说明 |
---|---|
Capacity |
获取或设置ArrayList可包含的元素数 |
Count |
获取ArrayList中实际包含的元素数 |
IsFixedSize | 获取一个值,该值指示ArrayList是否具有固定大小 |
IsReadOnly | 获取一个值,该值指示ArrayList是否可读 |
IsSynchronized | 获取一个值,该值指示是否同步对ArrayList的访问 |
Item |
获取或设置指定索引处的元素 |
SyncRoot | 获取可用于同步ArrayList访问的对象 |
注意:
(1)、ArrayList允许null值作为有效值,并且允许重复的元素。
(2)、如果ArrayList实际存储元素数已经等于ArrayList可存储的元素数,则会通过重新分配内部数组增加ArrayList的容量,并在添加新元素之前将现有元素复制到新数组中。
(3)、在程序中使用ArrayList类时,需要在命名空间区域添加using System.Collections。
注意:
(1)、在删除ArrayList中的元素时, 如果不包含指定对象,则ArrayList将保持不变。
(2)、在RemoveRange()方法中参数count的长度不能超出数组的总长度减去参数index的值。
Hashtable通常称为哈希表,它表示键/值对的集合,这些键/值对根据键的哈希表代码进行组织。它的每一个元素都是存储在DictionaryEntry对象中的键/值对。键不能为空引用,但值可以。
属性是一种用于访问对象或类的特性的成员,它可以表示字体的大小,窗体的标题和客户的名称等内容。
属性有访问器,这些访问器指定在它们的值被读取或写入时需要执行的语句。因此属性提供了一种机制,它把读取和写入对象的某些特性与一些操作关联起来。可以象使用公共数据成员一样使用属性,但实际它们是称为“访问器”的一种特殊方法,这使得数据在被轻松访问的同时,仍能提供方法的安全性和灵活性。
注意:
(1)、属性不能作为ref参数或out参数传递。
(2)、get访问器与方法体相似,它必须返回属性类型的值;而set访问器类似返回类型为void的方法,它使用称为value的隐式参数,此参数的类型是属性的类型。
(3)、如果要在其他类中调用自定义属性,必须将自定义属性的访问级别设置为public。
方法是一种用于实现可以由对象或类执行的计算或操作的成员。类的方法主要是和类相关联的动作,它是类的外部界面。对于那些私有的字段来说,外部界面实现对它们的操作一般只能通过方法来实现。
注意:
(1)、out关键字用来定义输出参数,它会导致参数通过引用来传递,这与ref关键字类似,不同之处在于ref要求变量必须在传递之前初始化,而使用out关键字定义的参数,不用进行初始化即可使用。如果要使用out参数,则方法声明和调用方法都必须显示使用out关键字。
(2)、静态方法不对特定实例进行操作,调用时,需要直接使用类名进行调用。非静态方法是对类的某个给定的实例进行操作,调用时,需要使用类的实例(对象)进行调用。
(3)、方法的重载是指方法名相同,但参数的数据类型、个数或顺序不同的方法。其他的都不属于方法的重载(例如,只返回类型的不同不属于方法的重载)。
(4)、Main()方法默认访问级别为private。
结构就是几个数据组成的数据结构,它与类共享几乎所有相同的语法,但结构比类受到的限制更多。
结构具有的特点如下:
①、结构是值类型的。
②、向方法传递结构时,结构时通过传值的方式传递的,而不是作为引用传递的。
③、结构体实例化可以不适用new运算符。
④、结构体可以声明构造函数,但它们必须带参数。
⑤、一个结构不能从另一个结构或类继承。所有结构都直接继承自System.ValueType,后者继承自System.Object。
⑥、结构可以实现接口。
⑦、在结构中初始化实例字段是错误的(在结构声明中,除非字段被声明为const或static,否则无法初始化)。
在程序开发初期人们使用结构化开发语言,但随着软件的规模越来越庞大,结构化语言的弊端也逐渐暴露出来,开发周期被无休止地拖延,产品的质量也不尽人意,结构化语言已经不在适合当前的软件开发。这时人们开始将另一种开发思想引入程序中,即面向对象的开发思想。面向对选哪个思想是人类最自然的一种思考方式,它将所有预处理的问题抽象为对象,同时了解这些对象具有哪些相应的属性以及展示这些对象的行为,已解决这些对象面临的一些实际问题,这样就在程序开发中引入了面向对象设计的概念,面向对象设计的实质上就是对现实世界的对象进行建模操作。
类(Class)实际上是对某种类型的对象定义变量和方法的原型,它表示对现实生活中一类具有共同特征的事物的抽象,是面向对象编程的基础。
注意:
(1)、不带参数的构造函数被称为“默认构造函数”。无论何时,只要使用new运算符实例化对象,并且不为new提供任何参数,就会调用默认构造函数。
(2)、一个类中只能有一个析构函数,并且无法调用析构函数,它是被自动调用的。
(3)、类的对象是引用类型。
(4)、每个对象都有生命周期,当对象的生命周期结束时,分配给对象的内存地址将会被回收(当对象引用超过其作用范围,则这个对象将被视为垃圾;当对象赋值为null时,对象也将被视为垃圾,将被销毁)。
注意:
(1)、继承类时,需要使用冒号加类名。当对一个类引用sealed修饰符时,此修饰符会阻止其他类从该类继承。
(2)、当重写父类方法时,修改方法的修饰权限只能从小的范围到大的范围改变,例如,父类中的doit()方法的修饰权限为protected,继承后子类中的方法doit()的修饰权限只能修改为public,不能修改为private。