第2章c#基础2.1引言C#是一种面向对象的语言,需要懂得类、对象、接口、继承的含义。2.2.3详细信息在c#中使用usingsystem指令的原因是下面要使用一个库类system.console.usingsystem指令允许把这个类简写为console(类似于system命名空间的其它类)。标准的system命名空间包含了最常用.net类型。我们用C#做的所有工作者依赖于.net基类。在本例中,我们使用了system命名空间console类,以写入控制窗口。C#没有输入输出的内置关键字,完全依赖于.net类。接着,声明一个类myfirstclass。C#中的代码都必须包含在一个类中,类的声明包括class关键字,其后是类名和一对花括号。与类相关的所有代码都包含在花括号内。下面声明方法Main()。每个c#可执行文件(例如控制台应用程序、windows应用程序和windows服务)都必须有一个入口点——Main方法StaticvoidMain()该方法要么没有返回值void,要么返回一个整数()。注意c#的方法定义如下:修饰符(modi)用于指定用户所定义方法的某些特性,例如可以在什么地方调用该方法。修饰符public表示可以任何地方访问该方法,所在可以在类的外部调用它。修饰符static表示方法不能在类的实例上执行,因此不必实例化再调用。因为我们创建的是一个可执行文件,而不是类库。把返回类型设置为void,在本例中,不包含任何参数。在本例中,我们只调用了system.Console类的writeline()方法,把一行文本写到控制台上。WriteLine()是一个静态方法,在调用之前不需要实例化console对象。然后调用return退出该方法(因为这是Main方法,所以也退出了应用程序)。在方法的首部指定void,因此没有返回值。C#有两个方法可确保变量在使用前进行了初始化:变量是类或结构中的字段,如果没有显式初始化,创建这些变量时,其值就默认是0.方法的局部变量必须在代码中显示初始化,之后才能在语句中使用它们的值。此时,初始化不是在声明该变量时进行的,但编译器会通过方法检查所有可以的路径,如果检测到局部变量在初始化之前就使用了它的值,就会产生错误。staticintMain(){intd=2;Console.WriteLine(d);return0;}定义Main(),使之返回一个int类型的数据,而不是void。定义void类型的数据,代表返回来的必须是空值,最后不能有return语句。SomethingobjSomething,这行代码会为something对象创建一个引用,但这个引用还没有指向任何对象。对该变量调用方法或属性会导致错误。在c#中实例化一个引用对象需要使用new关键字。创建一个引用,使用new关键字把该引用引用指向存储在堆上的一个对象。Objsomething=newSomething();Type表示类型的声明,包括类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。蓝色的表示局部变量。classProgram{staticvoidMain(string[]args){varname=BugsBunny;varage=25;varisRabbit=true;TypenameType=name.GetType();//nameTypeisobject,nameisvariable.TypeageType=age.GetType();TypeisRabbitType=isRabbit.GetType();Console.WriteLine(nameistype+nameType.ToString());}}变量必须初始化,否则编译器就没有推断变量类型的依据。变量的作用域:只要类在某个作用域内,其字段也在该作用域内。局部变量存在于表示声明该变量的语句或方法结束的封闭花括号之前的作用域内。在for、while或类似语句中声明的局部变量存在于该循环体内。注意:同名的局部变量不能在同一作用域内声明两次。2、在某些情况下,可以区分名称相同(尽管其完全限定的名称不同),作用域相同的两个标识符。些时编译器允许声明两个变量。原因是c#在变量之间有一个基本的区分,它把声明为类型级的变量看成是字段,而把方法中声明的变量看成是局部变量。如何引用类型变量?可以使用语法object.fieldname,在对象的外部引用类的字段或结构。在上面的例子中,我们访问静态方法中的一个静态字段,所以不能引用类的实例,只能使用类的本身。publicstaticvoidMain(){intj=30;Console.WriteLine(j);Console.WriteLine(scopeTest2.j);}如果要访问一个实例字段(该字段属于类的一个特定实例),就需要使用this关键字。3.常量就是其值在使用的过程中不会发生变化的变量。在声明和初始化变量时,在变量的前面加上关键字const,就可以把该变量指定为一个常量。常量具有以下特征:常量必须在声明时初始化,指定了其值后,就不能再修改了。常量的值必须在编译时用于计算。因此,不能用从一个变量中提取的值来初始化常量。如果需要这么做,应使用只读字段。常量总是静态的。但注意的是,不必在常量声明中包含修饰符static。2.4预定义类型C#对其可用的类型及其定义有严格的描述。C#数据类型:值类型和引用类型。从概念上看,其区别是值类型直接存储其值,而引用类型直接存储其引用。这两种类型存储在不同的地方:值类型存储在堆栈中,而引用类型存储在托管堆上。这两个类型不同,存储位置会有不同的影响。Inti=20值类型I=j引用类型代表一个类中的一个字段。2.5定义一个类Vector,Vector是一个引用类型,它有一个int类型的成员变量value。在执行这段代码后,只有一个Vector对象。X和y都指向包含该对象的内存位置。因为x和y都是引用类型的变量,声明这两个变量只保留了一个引用——而不会实例化给指定类型的对象。要创建对象,就必须使用int关键字。因为x和y都引用同一个对象,所以对x的修改会影响y.在c#中,基本数据类型bool和long都是值类型。如果声明一个bool变量,并给它赋予另一个bool变量的值,在内存中就会有两个bool值。修改第一个bool变量的值,第二个bool变量值也不会改变。大多数我复杂的c#数据类型,包括我们声明的类都是引用类型。它们分配在堆中,其生命周期可以跨多个函数调用,可以通过一个或几个别名来引用。把基本类型(如int和bool)规定为值类型,而把包含许多字段的较大型(通常在有类的情况下)规定为引用类型。如果要把自己的类型定义为值类型,就应把它声明一个结构。2.6C#认可的基本预定义类型并没有内置于c#语言中,而是内置于.netframework中。例如,在c#中声明一个int类型的数据,声明的实际上是.net结构System.Int32的一个实例。可以把所有的基本数据类型看成支持某些方法的类。strings=i.tostring();预定义的值类型:表示基本的数据类型:整型、浮点类型、字符类型、布尔类型。预定义的引用类型:object类型、string类型。在C#中,object类型就是最终的父类型,所有内置类型和用户定义的类型都是从它派生而来。Object类型可以用于两个目的:可以使用object类绑定任何子类型的对象。使用object类型把堆栈中的一个值对象装箱,再移动到堆中。Object类型执行许多一般用途的基本方法。用户定义的类需要使用一种面向对象技术——重写,提供其中一些方法的替代执行代码。例如,重写tostring(0时,要给类提供一个方法,给出类本身的字符串表示。C#有string关键字,在翻译为.net类时,它就是system.string。Stringstr1=“hello”尽管这是一个值类型的赋值,但string是一个引用类型。String对象保留在堆上。因此,当把一个字符串变量赋给另一个字符串时,会得到对内存中同一个字符串的两种引用。但是string与引用类型在常见的操作上有一些区别。例如,修改其中一个字符串,就会创建一个全新的string,而另一个对象没有改变。classProgram{staticvoidMain(string[]args){strings1=astring;strings2=s1;Console.WriteLine(s1is+s1);Console.WriteLine(s2is+s2);s1=anotherstring;Console.WriteLine(s1isnow+s1);Console.WriteLine(s2isnow+s2);}}换言,改变s1的值对s2没有影响,这与我们期望的引用类型正好相反。当用值“astring”初始化s1时,就在堆上分配了一个新的string对象。在初始化s2时,引用也指向这个对象,所以s2的值也是“astring”。但是,现在要改变s1的值,而不是替换原来的值时,堆上就会为新值分配一个对象。S2变量仍指向原来的值,所以它的值没有改变。这实际上是运算符重载的结果。字符串放在双引号,单引号里面是字符类型。2.6if后面的判断句用两个等号,if子句中的表达式必须等于布尔值。staticvoidMain(string[]args){switch(integerA){case1:Console.WriteLine();break;case2:break;default:break:}}Case的值必须是常量表达式,不允许使用变量。2.7枚举枚举是用户自定义的整数类型。要指定该枚举可以包含的一组可接受的实例值。不仅如此,还可以给值指定易于记忆的名称。定义下列的枚举:PublicenumTimeOfDay{Morning=0,Afternoon=1,Evening=2}注意:定义枚举中的内容用逗号连接。本例在枚举中使用一个整数值,来表示一天的每个阶段。现在可以把这些值做为枚举的成员来访问。例如,timeOfDay.morning返回数字0。使用这个枚举一般是把合适的值传递给方法,或在switch语句中迭代可能的值。classProgram{publicenumTimeOfDay{Morning=0,Afternoon=1,Evening=2}classEnumExample{publicstaticintMain(){WriteGreeting(TimeOfDay.Morning);TimeOfDaytime=TimeOfDay.Afternoon;//这个是使用定义枚举的方式Console.WriteLine(time.ToString());WriteGreeting(TimeOfDay.Morning);TimeOfDaytime=TimeOfDay.Afternoon;Console.WriteLine(time.ToString());TimeOfDaytime2=(TimeOfDay)Enum.Parse(typeof(TimeOfDay),afternoon,true);Console.WriteLine((int)time2);return0;}staticvoidWriteGreeting(TimeOfDaytimeOfDay){switch(timeOfDay){caseTimeOfDay.Morning:Console.WriteLine(Goodmorning);break;caseTimeOfDay.Afternoon:Console.WriteLine(Goodafternoon!);break;caseTimeOfDay.Evening:Console.WriteLine(Goodevening);break;default:Console.WriteLine(Hello);break;}}}}在c