C#入门课程01
第一次课
一、面向对象的重要概念
面向对象设计方法(或面向对象设计思想)本身是独立于编程语言的,在这种设计方法中提出了类和对象两个顶级概念和三个特征:封装、继承、多态。实现了这两个概念和三个特征的程序语言,我们称之为面向对象的程序设计语言。我们所学的C#语言就是面向对象的程序设计语言。
计算机软件主要就是为了模拟现实世界中的不同系统,如物流系统、银行系统、图书管理系统、教学管理系统等。面向对象的设计方法使得计算机更易于模拟现实世界。面向对象设计方法所提出的重要概念均来自我们现实的生活中,因此在学习面向对象程序设计语言之前,先在生活中建立起这些概念是有必要的。
对象是可以想象到的任何东西。概括来说就是:万事万物,一切皆为对象。
对象都有其特征:状态、行为以及唯一的标识。
类是对一系列据有相同性质的对象的抽象,是对对象共同特征的描述。是创建对象的模板。在编程时先定义类然后才能创建相应的对象。
我们在生活中所见到的对象都有隐蔽实现细节的特征,我们称之为封装。封装的特征使我们在使用对象时不必了解其制造过程和实现原理,只需要了解其提供哪些功能即可。
继承是父与子的关系,子可以重用父的东西。比如继承下来的财产,并不会因为是父代传下来的财产子代就不可以使用,我们都知道子代是可以重用的。
多态简单来说就是多种状态,有两种情况,一种情况是同一事物在不同的条件下所处的状态不同,比如水根据温度的变化会处在不同的状态下,另一种情况是同一事物在不同的条件下表现出的行为不同,比如同学会根据距离上课时间的多少采取走或跑的行为。在程序设计语言中所实现的多态主要是后一种情况。
二、第一个程序HelloWorld
欢迎来到C#世界,这是学习每门语言前都会看到的小程序。HelloWorld程序虽然短小但包含的内容却很多。主要讲述了以下内容:
1、Main方法是程序的入口,程序得到运行时首先进入Main方法,并按Main方法中语句的先顺序执行。一个程序中Main方法只能有一个。
2、csc编译器用于把源程序翻译成01代码的可执行程序。
3、Console.WriteLine() 可把字符串输出到控制台。Console.ReadLine()可把用户输入读到程序中。Console.ReadLine()读入的数据为字符串型。
4、Console是.Net定义的一个类,像这种.Net定义的类有很多我们可以直接拿来使用,Console类定义在了System命名空间下。命名空间是管理类的一种方式,它就好像文件夹,在同一个命名空间下的类不能重名,在不同命名空间下类可以重名,每个类必需包含在一个命名空间里,如果不使用using来引入命名空间的话,使用相应命名空间下的类时必须写明命名空间。如:
使用using引入System命名空间
using System;
Console.WriteLine(“123”);
不使用using 引入System命名空间
System.Console.WriteLine(“123”);
System命名空间下的类还有很多,多是提供常用功能的类。
5、class关键字,关键字是C#保留使用的,都有其特殊意义,不能使用关键字作为变量名或其他名字。class关键字用于定义类,后跟类名,还有一对大括号来说明定义范围。如
class MyClass
{
}
6、每条语句后面以分号“;”结束。
三、转义字符
常用的有 " "" "" "r "n
转义字符只能使用在字符串中。
第二次课
一、使用面向对象的方法分析解决问题
学习了面向对象就应以面向对象的方法去分析处理问题,首先应以面向对象的眼光看待整个世界,万事万物一切皆为对象,这就是面向对象的世界观。
在解决一个问题时:
第一先分析问题中有哪些对象。
第二分析每个对象的状态和行为,有的对象可能只有状态,有的对象可能只有行为,一切根据问题的需要而定。
第三分析对象之间的关系。
第四根据分析结果设计类,只有先定义类,才能创建相应的对象。
第五根据前面的分析与设计,写出程序。
二、基本数据类型
int float double bool char string
这些数据类型是C#内置的数据类型必须记住。
int 整形用来存放整数。
float 单精度浮点数
double 双精度浮点数
bool 布尔类型 存放ture 或 false
char 字符类型 存放单个字符 'a '字符用单引号阔起来
string 字符串型 存放字符串 "1234 "字符串用双引号括起来。
三、声明变量
1、变量声明: 数据类型 变量名; 例如 int num;
2、常量声明: const 数据类型 变量名=值;
例如 const int num=34;
3、为变量第一次赋值称之为初始化变量,在声明常量时必须为常量初始化,即在声明常量时就为常量赋值。
4、为变量赋的值的类型必须和变量声明的数据类型一致。
有两种情况可以不一致。
第一类型之间可以隐式转换,隐式转换的内容在课本2.6页最后一段提到,但不赞成使用隐式转换,隐式转换可造成数据丢失而得到不期望的结果,特别是无意的隐式转换有时会让你感到疑惑。
第二类型之间可以兼容,在学习继承时会提到,子类与父类是兼容的。
四、值类型和引用类型
内存可看成两个区域,一个区域为栈,另一个区域为堆。声明变量所分配的内存都在栈中,值类型和引用类型的区别主要在于数据的存储位置不同,值类型的数据放在栈中,引用类型的数据放在堆中,而变量中存的是指向堆中数据的一个地址。值类型和引用类型变量在使用时并没有差别,因为作为引用类型的变量,系统会根据变量中所存的地址找到堆中的数据。
五、注释
// 为单行注释
/* */ 为多行注释
注释主要用在对程序的说明。编译器将忽略被注释的程序,利用这一点可以帮助我们调试程序。
六、数据类型转换
当我们需要给变量所赋的值的数据类型与变量声明时的数据类型不一致时,需要进行数据类型的转换,我们通常提倡数据类型的显式转换,即在写程序时明确告知想要转成什么类型。
Convert.ToInt32();可以帮我们把数据转换成int型。
Convert.ToSingle();可以帮我们把数据转换成float型。
还有一种显示转换的方式:
例如: int num;
num=(int)3.6;
这样做可以把小数3.6显示转换为整数3。这种方式在C#入门经典75页提到了。目前应用并不多,一般都使用Convert来转换。
数据类型的转换在以后会经常碰到,你会发现在写程序时做的最多的就是数据类型之间的转换,而通常容易出错的地方也是数据类型的转换问题。
第三次课
一、补充的数据类型
|
类型 |
范围 |
大小 |
|
-128 到 127 |
有符号 8 位整数 | |
|
0 到 255 |
无符号 8 位整数 | |
|
U+0000 到 U+ffff |
16 位 Unicode 字符 | |
|
-32,768 到 32,767 |
有符号 16 位整数 | |
|
0 到 65,535 |
无符号 16 位整数 | |
|
-2,147,483,648 到 2,147,483,647 |
有符号 32 位整数 | |
|
0 到 4,294,967,295 |
无符号 32 位整数 | |
|
-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
有符号 64 位整数 | |
|
0 到 18,446,744,073,709,551,615 |
无符号 64 位整数 | |
|
decimal |
±1.0 × 10e−28 至 ±7.9 × 10e28 |
28 到 29 位有效位 |
|
±1.5e−45 到 ±3.4e38 |
7 位 | |
|
±5.0e−324 到 ±1.7e308 |
15 到 16 位 |
二、操作符
1、算数操作符,关系操作符,逻辑操作符和赋值操作符与编程逻辑中的含义一样。
需要注意的是== 和!=可以比较字符串,现阶段这一特点很有用,因为从控制台读入的数据就是字符串型。可进行字符串的比较。
< > <= >=只能比较比较数值或者是字符,在比较字符时系统会根据字符编码把字符转成十进制的整数进行比较。
2 、++ 和 --
++进行加1操作,--进行减1操作ch。
分为前置和后置两种情况。
前置:例如 ++i,先对i加1然后再使用i的值。
后置:例如i++,先使用i的值然后再对i加1。
测试:程序一
b=++i;
Console.WriteLine(b);
Console.WriteLine(a);
程序二
b=i++;
Console.WriteLine(b);
Console.WriteLine(a);
体会前置与后置的不同。
三、if……else 分支结构(或称选择结构)
if(判断条件)
{
语句;
}
else
{
语句;
}
判断条件由关系表达式或逻辑表达式构成,判断条件只能写在if后面的小括号里,有些同学会在小括号后面加上分号,这是错误的,要注意。当条件为ture时执行if后面花括号中的语句,当条件为false时执行else后面花括号中的语句。写if结构时可以只写一个单if不加else,主要用来在条件不满足时跳过一些语句。单if:
if(条件)
{
语句;
}
if……else结构可以嵌套,嵌套层数没有限制,不管嵌套多少层,他们始终是一个整体,只会沿一条路走,而不会走两条路,看看下面的if…else嵌套,你会认为他有什么样的输出呢?
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
int num=12;
if (num > 5)//1号if
{
if (num > 10)//2号if
{
Console.WriteLine("2号if");
}
else//1号else
{
Console.WriteLine("1号else");'
}
}
else if (num > 10)//2号else 3号if
{
Console.WriteLine("2号else 3号if");
}
else//3号else
{
Console.WriteLine("3号else");
}
Console.ReadKey();
}
}
}
答案:将输出 2号if
四、while 和do…while循环
while(循环条件)
{
循环体;
}
do
{
循环体;
}while(循环条件);
在写do…while循环时不要忘记最后面的分号。循环条件为关系表达式或者逻辑表达式,当判断为true时执行花括号里面的语句,当判断为false时结束循环。while循环是先判断循环条件再执行花括号里面的语句,do…while循环是先执行花括号里面的语句再判断循环条件,do…while循环至少执行一次花括号里面的语句,而while循环可能一次都不执行。这一点要注意。
循环可分为,固定次数的循环,不固定次数的循环和无限循环(死循环)。固定次数的循环需要有循环变量来控制循环次数。不固定次数的循环需要通过对问题的分析找到退出循环的判断条件。无限循环比如while(true)判断条件始终为true,这种循环将无休止的循环下去,因此需要在内部设置退出循环的条件,一般以命令的方式,当满足自定的命令时可使用break;来跳出无限循环。具体怎么做看课上举的实例。
第四次课
一、switch…case选择结构
switch(变量或算数表达式)
{
case 具体的值:{语句; break;}
case 具体的值:{语句; break;}
case 具体的值:{语句; break;}
default :{语句; break;}
}
在小括号内可以放变量或算数表达式,变量的类型必须是字符串,字符或整型,表达式所计算的结果也必须是这三种类型。case后面跟具体的值不能是一个数值范围,每个case所执行的语句最后都必须加上break;语句,在所有case的后面还要有default。
当程序进入switch结构后case后面所带的值会和小括号中的变量的值比较如果相等则执行相应case后面的语句,执行完毕后跳出switch结构。如果没有相等的则执行default后面的语句,执行完后跳出switch结构。Default可以省略,但建议不要省略。
利用switch结构可以帮我们在控制台应用程序中设置菜单,显示一个菜单给用户,让用户输入对应的数字来选择菜单项,使用switch来判断用户的输入,从而执行相应的case分支来完成功能。具体看课上实例。
二、for循环
for (声明循环变量并赋初值; 循环条件;循环变量自增或自减 )
{
循环体;
}
for循环主要应用在固定次数的,它比while和do…while循环更常用,因此要很熟练的掌握for循环的写法。
for循环在运行时首先执行声明循环变量赋初值的操作(由于变量作用域的问题有可能在for循环外面声明循环变量,而在这里只赋初值)这个操作在整个循环中只做一次,然后先判断循环条件,如果条件为true则执行花括号里面的语句,当执行完花括号里面的语句后改变循环变量的值,再判断,再执行语句直到条件判断为假时退出循环。
在写for循环时要注意两个分号不能少也不能多。for循环括号里面的三个部分可以任意省略,但分号不能省略。虽然可以省略但不建议这样做。
三、break和continue的区别
1、break可以跳出所在层循环,如果有两个循环嵌套在一起,则内层循环中的break只会跳出内层循环而不会跳出两层,这要注意。另外要注意的是break也可以使用在switch结构里面,如果一个循环里面有switch结构,则switch结构里面的break只会跳出switch结构而不会跳出外层的循环。
2、continue只能用在循环中,在循环中遇到continue后,则不会执行continue后面的语句,而直接进入下一次循环,并不会跳出循环。这一点是和break有很大的区别。
第五次课
在这一次课中主要介绍了方法的使用,方法是程序设计中必不可少的组成部分,如果没有方法,那我们的所有程序都将只能写在Main方法中,这种限制是难以接受的。因此掌握方法的使用是有必要的。
一、方法是一组相关程序的集合,通常用来完成一定的功能,也可以把方法称为子程序。
当程序运行时,只会执行Main方法中的语句,写在其他方法中的程序不会得到执行,如果想要执行其他方法中的程序,必须要调用方法。这就像一辆汽车(其他方法),光停在那里汽车自己不会开走,必须有人(Main方法)去踩油门(调用方法)车才会移动。如果这辆汽车后面还拖着其他车(在其他方法中调用的方法),那么被拖得车也会一起移动。
方法的调用执行过程:当在程序运行时,如果碰到了方法名字,程序就会立即转到相应的方法内部执行,当方法中的语句执行完毕后,立即返回,然后再执行方法名后面的语句。
Main() 方法名
|
|
|
2-------------; 2----------------;
方法名; }
|
|
4--------------;
}
执行的顺序为:1 2 1 2 3 4
二、方法需要声明在类的范围内,可以把方法看成是类的成员,因此又称作成员方法。目前可把方法分为实例方法和静态方法,实例方法和静态方法在声明上只差static关键字。这次课主要讲了实例方法。
声明实例方法的格式:
[访问修饰符] 返回值类型 方法名([数据类型 参数名,数据类型 参数名……])
{
方法体
}
目前需要掌握的访问修饰符有两个public 和 private ,访问修饰符可以省略,如果省略默认为private。
参数列表可以省略,省略说明此方法没有参数。在声明参数时须指定参数的数据类型和参数名,多个参数之间必须用逗号分隔。虽然被声明的参数并没有占用任何内存,也没有任何值,但在方法体内可以直接使用。在调用方法时,如果方法定义了参数,必须为方法传参。
在方法执行完程序返回时,有可能希望带回一个结果。比如有一个方法用来求n个数的和,在方法执行完后返回时,希望得到和值。像这样的值我们称为方法的返回值。方法所返回的值的类型由方法声明中的返回值类型决定,值的类型必须和所规定的返回值类型相匹配。如果方法没有返回值则返回值类型为void,在方法体中不能使用return语句返回任何值。如果有返回值,则在方法体中必须使用return返回值。
三、方法的调用规则:
1、方法所在类的内部:静态方法不能直接通过名字调用实例方法,必须创建对象后通过“.”操作符来调用方法。实例方法之间可直接通过方法名字调用。
2、方法所在类的外部:必须创建对象后通过“.”操作符来调用方法,而且只能调用到访问修饰符为public的实例方法,不能调用到访问修饰符为private的方法。public是公开的,private是私有的只能在类的内部使用。
3、在调用方法时注意不要忘记小括号,如果被调用的方法有参数,必须传参。在传参数时需要注意参数个数、参数类型和参数顺序必须匹配。
四、创建对象
创建对象需要用到new关键字。例如:Ball ball=new Ball(); 创建了一个Ball类的对象并把这个对象存在了ball变量中。在这里ball只是一个变量,至于什么时候给ball赋值,以什么样的方法赋值,须根据情况而定。这一点要注意。
五、调试
1、可以为程序设置断点,按F11键进行单步执行。在程序出现逻辑错误时,可利用此方法查找错误。
2、在出现语法错误时,可以在相应的错误提示上双击鼠标左键,会自动定位到出现错误的行,方便查找错误。
六、局部变量
在程序中所声明的变量是都有自己的作用域,在作用域之外变量就会消亡,变量的作用域被限制在声明时所在的那一对大括号里。现在所声明的变量都在方法的范围内,这个方法执行完后,方法内所定义的变量都将消失,我们称这种在方法内部声明的变量为局部变量,在从局部变量获取值之前必须为其赋值。
第六次课
这次课中主要介绍了类的另外两个成员:成员变量和成员属性。还有值传递和引用传递。
一、成员变量
1、成员变量分实例成员变量和静态成员变量,本次重点说明实例成员变量。
2、成员变量也是一种变量,主要用于存储与对象有关的数据,比如球类有品牌,价格等,将其定义为相应的成员变量,当创建不同的球类对象时,成员变量可用来存储不同球类对象的品牌和价格数据。
3、成员变量的声明:[访问修饰符] 数据类型 变量名;
访问修饰符所表示的含义与方法的访问修饰符一样,如省略默认为private。成员变量必须声明在类的范围内。例如:
class Ball
{
private string brand;//定义了用于存储球类对象品牌数
//据的成员变量
private float price; //定义了用于存储球类对象价格数
//据的成员变量
}
在声明时可以为成员变量赋一个初始值。例如:
class Ball
{
private string brand="耐克";
private float price=100.3f;
}
4、实例成员变量的使用规则:
A、在成员变量所在类的外部,需创建对象后用“.”操作符来使用访问修饰符为public的成员变量,可赋值也可获取值。
B、在成员变量所在类的内部,静态方法不能直接通过名字使用成员变量,应先创建对象。
C、在成员变量所在类的内部,实例方法可以直接通过名字来使用成员变量。
D、访问修饰符为public和private的成员变量都可在其所在类的内部使用。
5、实例成员变量和局部变量的区别
A、声明在方法中的变量为局部变量,其作用域在声明它的方法中,而成员变量声明在类的范围内,其作用域在类中,在同一个类中多个实例方法可以使用同一个成员变量,例如一个方法为成员变量赋值,而另一个方法可以获取同一个成员变量中的值。这是局部变量做不到的。
B、在使用获取局部变量中的值时必须先为局部变量赋值。而成员变量不同,在获取成员变量中的值时不需要为成员变量先赋值,系统会为成员变量赋一个初始值,当然这个值通常没有意义,比如数值类型的成员变量,系统会为其赋为0。
6、在什么时候需要声明成员变量和成员方法
A、在类的内部多个实例方法需要使用同一个变量时需把此变量声明为成员变量。
B、在对实际问题所涉及的对象分析后,分析出的对象的状态需定义为相应类的成员变量。
C、在对实际问题所涉及的对象分析后,分析出的对象的行为需定义为相应类的成员方法。
7、创建对象后为成员变量赋值,例如:
Ball myball = new Ball();
myball.brand = "阿迪达斯";
创建对象后取得成员变量的值,例如:
string str = myball.brand;
二、属性
1、为什么要使用属性
当把成员变量的访问修饰符设为public后,在创建对象后可为成员变量赋任何类型一致的值。但某些值是毫无意义或者有悖常理的。比如说一个职工的年龄不可能为负数等等。因此直接让成员变量为public在某些时候是不合适的。为了能够限制客户的输入,可以使用属性把成员变量封装起来。让成员变量为private,相应的属性为public。
例如:class Ball
{
private string brand;
public string Brand
{
get { return brand; }
set { brand = value; }
}
}
2、使用属性
属性包括get访问器和set访问器,get访问器用来返回成员变量的值,set访问器用来为成员变量赋值。在这两个访问器中可以写程序,通常在set访问器中判断赋值是否有效。这一点在.Net类库中应用的很频繁。set访问器和get访问器可任意省略一个,只有get访问器的属性只能获取成员变量的值,称为只读属性。只有set访问器的属性只能为成员变量赋值,成为只写属性。在实际开发中,只读属性还是比较常见的。为属性赋值和获取值得方式与成员变量相同。
例如: Ball myball = new Ball();
myball.Brand = "阿迪达斯";//Brand为Ball类的一个属性
三、按值传递和按引用传递
1、实参与形参:在方法中定义参数称为形参,调用方法时为方法传递的参数为实参。如果方法定义了参数,则在调用方法时必须为方法传递相应的参数。方法定义的参数,在方法内部可以直接使用。
例如:
public int Sum(int num1, int num2)
{
int sum;
sum = num1 + num2;//因为num1和num2被声明为了参数,在这里可以直接使用。他们的值将
return sum; //在方法被调用时被确定。
}
2、值类型按值传递参数,传入的是实参的副本。将实参的副本传给形参,在方法内部修改形参的值,不会影响到实参。值类型按引用传递,可理解为把实参本身传给了形参,这样在方法内部修改形参的值,也就修改了实参的值。
3、引用类型传参,在这里可以理解为总是把(所传的对象)本身传给形参,这样在方法内部修改引用类型对象的成员变量或属性的值时也就相当于把实参(所传的对象)的成员变量或属性的值修改了。
四、关于使用类作为参数的数据类型和返回值类型
类是一种自定义的数据类型,而且是一种引用类型,我们每定义一个类就相当于定义了一种数据类型,这个数据类型的名字就是所起的类名。因此他可以作为参数的类型和返回值的类型。
例如:public void Set(Ball ball)
{
ball.brand = "阿迪达斯";
}
public Ball Set()
{
Ball ball = new Ball();
return ball;
}
这个例子说明了两件事:
1、当用类名作为参数的数据类型时,在调用此方法时须传入此类型的对象。传参后,在方法内部就可以使用这个传入的对象了。
2、当用类名作为返回值类型时,说明此方法将返回此类型的对象。
当把这个返回地对象赋给一个变量,那么就可以通过这个变量来使用这个对象了。
五、关于在什么时候为方法声明参数
当在方法中的某些变量的值是需要客户程序(即调用此方法的程序)来提供,则把此变量声明为参数,因为在调用方法时必须为参数传值。反之,这些变量的值可以在方法内部确定,则不要声明为参数。
第七次课
这次课主要静态成员,方法重载与查询MSDN
一、静态成员
1、静态成员与实例成员在声明上只差static关键字。
2、静态成员的使用规则:
A、在定义静态成员的类的外部,需使用类名用“.”操作符来使用访问修饰符为public的静态成员,而不能通过创建对象来使用。
例如:
class Program
{
static void Main(string[] args)
{
Test.Display();//在Test类的外部,使用Test的静态
//成员,需要类名按点来使用。
}
}
class Test
{
static public void Display()
{
Console.WriteLine("123");
}
}
B、在定义静态成员的类的内部
静态方法可直接通过名字来调用其它静态方法,静态方法可直接通过名字来使用静态成员变量。
静态方法不可直接通过名字来使用实例成员,需创建对象。
实例方法可直接通过名字来调用静态方法,实例方法可直接通过名字来使用静态成员变量。
例如:
class Test
{
static public void Display()
{
Console.WriteLine("123");
Ok();//在类的内部 静态方法可以直接通过方法的名
//字来调用静态方法。
}
static private void Ok()
{
Console.WriteLine("ok");
}
}
3、静态成员和实例成员的区别
A、在类外的使用方式不同,访问修饰符为public的实例成员需创建对象用“.”操作符使用。访问修饰符为public的静态成员需用类名用“.”操作符使用。
B、静态成员与实例成员的创建时间不同,在程序运行时一碰到类名(即第一次使用类时)类中的所定义的静态成员就创建完成了,而此时实力成员还未创建,这也说明了为什么静态方法中不能通过名字使用实例成员。
C、成员变量的副本数目不同,实力成员变量是每个对象一份副本,一个对象改变了自己的成员变量的值不会影响其他的对象,而静态成员变量是所有对象共享一份。
二、方法重载
1、方法签名:方法签名是方法名和参数列表(包括参数个数,参数类型,参数的顺序)的组合。方法签名与参数名和返回值类型无关。方法签名可以唯一的确定一个方法,在同一个类里面不能定义签名相同的多个方法。在不同的类里面可以定义签名相同的方法。
2、方法重载:在同一个类里面,方法名相同而参数列表不同的多个方法构成方法重载。如果多个方法的功能相同或者类似,建议使用方法重载,这样只要为这些方法起一个名字就可以了,不必去想多个方法名了。请注意同名的多个方法,参数列表不能相同。
例如:class Test
{
public int Max(int num1, int num2)
{
//语句;
}
public double Max(double num1, double num2)
{
//语句;
}
}
在同一个类里面的两个Max方法构成了方法重载。
三、查阅MSDN
MSDN是微软提供的帮助文档,对于程序员来说MSDN是很重要的,特别是在MSDN中对于微软提供的类库的说明很详细并有示例,在实际编程中主要是使用这个类库来进行的。微软提供的类库中有很多类,全部掌握并记住几乎是不可能的,对于一些不常用的类在使用时就需要查阅MSDN,因此学会查阅MSDN是有必要的。
目前从MSDN中查阅时需要注意以下几点:
1、类:了解此类的功能,看看它主要提供哪些功能,能帮你做什么事情。
2、类的方法:方法的功能、参数类型与参数的含义、返回值类型
3、类的属性:属性的作用、属性的类型、属性的取值范围、是否为只读属性。
4、MSDN还提供了C#语法的详细说明和编程指南,在忘了的时候可以查阅,见图


C#编程指南和参考 .NET类库

浙公网安备 33010602011771号