01 C# 程序结构和数据类型.docx
- 文档编号:30711839
- 上传时间:2023-08-19
- 格式:DOCX
- 页数:52
- 大小:45.01KB
01 C# 程序结构和数据类型.docx
《01 C# 程序结构和数据类型.docx》由会员分享,可在线阅读,更多相关《01 C# 程序结构和数据类型.docx(52页珍藏版)》请在冰豆网上搜索。
01C#程序结构和数据类型
1.1Helloworld1
1.2程序结构2
1.3类型和变量4
1.4表达式6
1.5语句8
1.6类和对象11
1.6.1成员12
1.6.2可访问性12
1.6.3基类13
1.6.4字段13
1.6.5方法14
1.6.5.1参数14
1.6.5.2方法体和局部变量15
1.6.5.3静态方法和实例方法16
1.6.5.4虚方法、重写方法和抽象方法17
1.6.5.5方法重载19
1.6.6其他函数成员20
1.6.6.1构造函数21
1.6.6.2属性21
1.6.6.3索引器22
1.6.6.4事件22
1.6.6.5运算符23
1.6.6.6析构函数23
1.7结构24
1.8数组25
1.9接口26
1.10枚举27
1.11委托28
1.12属性29
1.简介
C#(读作“SeeSharp”)是一种简单、现代、面向对象且类型安全的编程语言。
C#起源于C语言家族,因此,对于C、C++和Java程序员,可以很快熟悉这种新的语言。
C#已经分别由ECMAInternational和ISO/IEC组织接受并确立了标准,它们分别是ECMA-334标准和ISO/IEC23270标准。
Microsoft用于.NETFramework的C#编译器就是根据这两个标准实现的。
C#是面向对象的语言,然而C#进一步提供了对面向组件(component-oriented)编程的支持。
现代软件设计日益依赖于自包含和自描述功能包形式的软件组件。
这种组件的关键在于,它们通过属性(property)、方法(method)和事件(event)来提供编程模型;它们具有提供了关于组件的声明性信息的属性(attribute);同时,它们还编入了自己的文档。
C#提供的语言构造直接支持这些概念,这使得C#语言自然而然成为创建和使用软件组件之选。
C#的一些特性为构造强健和持久的应用程序提供了支持:
垃圾回收(Garbagecollection)将自动回收不再使用的对象所占用的内存;异常处理(exceptionhandling)提供了结构化和可扩展的错误检测和恢复方法;类型安全(type-safe)的语言设计则避免了引用未初始化的变量、数组索引超出边界或执行未经检查的类型强制转换等情形。
C#具有一个统一类型系统(unifiedtypesystem)。
所有C#类型(包括诸如int和double之类的基元类型)都继承于一个唯一的根类型:
object。
因此,所有类型都共享一组通用操作,并且任何类型的值都能够以一致的方式进行存储、传递和操作。
此外,C#同时支持用户定义的引用类型和值类型,既允许对象的动态分配,也允许轻量结构的内联存储。
为了确保C#程序和库能够以兼容的方式逐步演进,C#的设计中充分强调了版本控制(versioning)。
许多编程语言不太重视这一点,导致采用那些语言编写的程序常常因为其所依赖的库的更新而无法正常工作。
C#的设计在某些方面直接考虑到版本控制的需要,其中包括单独使用的virtual和override修饰符、方法重载决策规则以及对显式接口成员声明的支持。
本章的其余部分将描述C#语言的基本特征。
尽管后面的章节会更为详尽,有时甚至逻辑缜密地对规则和例外情况进行描述,但本章的描述力求简洁明了,因而难免会牺牲完整性。
这样做是为了向读者提供关于该语言的概貌,一方面使读者能尽快上手编写程序,另一方面为阅读后续章节提供指导。
1.1Helloworld
按照约定俗成的惯例,我们先从“Hello,World”程序着手介绍这一编程语言。
下面是它的C#程序:
usingSystem;
classHello
{
staticvoidMain(){
Console.WriteLine("Hello,World");
}
}
C#源文件的扩展名通常是.cs。
假定“Hello,World”程序存储在文件hello.cs中,可以使用下面的命令行调用MicrosoftC#编译器编译这个程序:
cschello.cs
编译后将产生一个名为hello.exe的可执行程序集。
当此应用程序运行时,输出结果如下:
Hello,World
“Hello,World”程序的开头是一个using指令,它引用了System命名空间。
命名空间(namespace)提供了一种分层的方式来组织C#程序和库。
命名空间中包含有类型及其他命名空间—例如,System命名空间包含若干类型(如此程序中引用的Console类)以及若干其他命名空间(如IO和Collections)。
如果使用using指令引用了某一给定命名空间,就可以通过非限定方式使用作为命名空间成员的类型。
在此程序中,正是由于使用了using指令,我们可以使用Console.WriteLine这一简化形式代替完全限定方式System.Console.WriteLine。
“Hello,World”程序中声明的Hello类只有一个成员,即名为Main的方法。
Main方法是使用static修饰符声明的。
静态(static)方法不同于实例(instance)方法,后者使用关键字this来引用特定的对象实例,而静态方法的操作不需要引用特定对象。
按照惯例,名为Main的静态方法将作为程序的入口点。
该程序的输出由System命名空间中的Console类的WriteLine方法产生。
此类由.NETFramework类库提供,默认情况下,MicrosoftC#编译器自动引用该类库。
注意,C#语言本身不具有单独的运行时库。
事实上,.NETFramework就是C#的运行时库。
1.2程序结构
C#中的组织结构的关键概念是程序(program)、命名空间(namespace)、类型(type)、成员(member)和程序集(assembly)。
C#程序由一个或多个源文件组成。
程序中声明类型,类型包含成员,并且可按命名空间进行组织。
类和接口就是类型的示例。
字段(field)、方法、属性和事件是成员的示例。
在编译C#程序时,它们被物理地打包为程序集。
程序集通常具有文件扩展名.exe或.dll,具体取决于它们是实现应用程序(application)还是实现库(library)。
在以下示例中:
usingSystem;
namespaceAcme.Collections
{
publicclassStack
{
Entrytop;
publicvoidPush(objectdata){
top=newEntry(top,data);
}
publicobjectPop(){
if(top==null)thrownewInvalidOperationException();
objectresult=top.data;
top=top.next;
returnresult;
}
classEntry
{
publicEntrynext;
publicobjectdata;
publicEntry(Entrynext,objectdata){
this.next=next;
this.data=data;
}
}
}
}
在名为Acme.Collections的命名空间中声明了一个名为Stack的类。
这个类的完全限定名为Acme.Collections.Stack。
此类中包含以下几个成员:
一个名为top的字段,两个分别名为Push和Pop的方法和一个名为Entry的嵌套类。
Entry类又进一步包含三个成员:
一个名为next的字段,一个名为data的字段和一个构造函数。
假定将此示例的源代码存储在文件acme.cs中,执行以下命令行:
csc/t:
libraryacme.cs
将此示例编译为一个库(没有Main入口点的代码),并产生一个名为acme.dll的程序集。
程序集包含中间语言(IntermediateLanguage,IL)指令形式的可执行代码和元数据(metadata)形式的符号信息。
在执行程序集之前,.NET公共语言运行库的实时(JIT)编译器将程序集中的IL代码自动转换为特定于处理器的代码。
由于程序集是一个自描述的功能单元,它既包含代码又包含元数据,因此,C#中不需要#include指令和头文件。
若要在C#程序中使用某特定程序集中包含的公共类型和成员,只需在编译程序时引用该程序集即可。
例如,下面程序使用来自acme.dll程序集的Acme.Collections.Stack类:
usingSystem;
usingAcme.Collections;
classTest
{
staticvoidMain(){
Stacks=newStack();
s.Push
(1);
s.Push(10);
s.Push(100);
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
}
}
如果此程序存储在文件test.cs中,那么在编译test.cs时,可以使用编译器的/r选项引用acme.dll程序集:
csc/r:
acme.dlltest.cs
这样将创建名为test.exe的可执行程序集,运行结果如下:
100
10
1
C#允许将一个程序的源文本存储在多个源文件中。
在编译多个文件组成的C#程序时,所有源文件将一起处理,并且源文件可以自由地相互引用—从概念上讲,就像是在处理之前将所有源文件合并为一个大文件。
C#中从不需要前向声明,因为除了极少数的例外情况,声明顺序无关紧要。
C#不限制一个源文件只能声明一个公共类型,也不要求源文件的名称与该源文件中声明的类型匹配。
1.3类型和变量
C#中有两种类型:
值类型(valuetype)和引用类型(referencetype)。
值类型的变量直接包含它们的数据,而引用类型的变量存储对它们的数据的引用,后者称为对象。
对于引用类型,两个变量可能引用同一个对象,因此对一个变量的操作可能影响另一个变量所引用的对象。
对于值类型,每个变量都有它们自己的数据副本(除ref和out参数变量外),因此对一个变量的操作不可能影响另一个变量。
C#的值类型进一步划分为简单类型(simpletype)、枚举类型(enumtype)和结构类型(structtype),C#的引用类型进一步划分为类类型(classtype)、接口类型(interfacetype)、数组类型(arraytype)和委托类型(delegatetype)。
下表为C#类型系统的概述。
类别
说明
值类型
简单类型
有符号整型:
sbyte,short,int,long
无符号整型:
byte,ushort,uint,ulong
Unicode字符:
char
IEEE浮点型:
float,double
高精度小数:
decimal
布尔型:
bool
枚举类型
enumE{...}形式的用户定义的类型
结构类型
structS{...}形式的用户定义的类型
引用类型
类类型
所有其他类型的最终基类:
object
Unicode字符串:
string
classC{...}形式的用户定义的类型
接口类型
interfaceI{...}形式的用户定义的类型
数组类型
一维和多维数组,例如int[]和int[,]
委托类型
delegateTD(...)形式的用户定义的类型
八种整型类型分别支持8位、16位、32位和64位整数值的有符号和无符号的形式。
两种浮点类型:
float和double,分别使用32位单精度和64位双精度的IEEE754格式表示。
decimal类型是128位的数据类型,适合用于财务计算和货币计算。
C#的bool类型用于表示布尔值—为true或者false的值。
在C#中,字符和字符串处理使用Unicode编码。
char类型表示一个16位Unicode编码单元,string类型表示16位Unicode编码单元的序列。
下表总结了C#的数值类型。
类别
位数
类型
范围/精度
有符号整型
8
sbyte
–128...127
16
short
–32,768...32,767
32
int
–2,147,483,648...2,147,483,647
64
long
–9,223,372,036,854,775,808...9,223,372,036,854,775,807
无符号整型
8
byte
0...255
16
ushort
0...65,535
32
uint
0...4,294,967,295
64
ulong
0...18,446,744,073,709,551,615
浮点数
32
float
1.5 × 10−45至3.4 × 1038,7位精度
64
double
5.0 × 10−324至1.7 × 10308,15位精度
小数
128
decimal
1.0 × 10−28至7.9 × 1028,28位精度
C#程序使用类型声明(typedeclaration)创建新类型。
类型声明指定新类型的名称和成员。
有五种类别的C#类型是可由用户定义的:
类类型、结构类型、接口类型、枚举类型和委托类型。
类类型定义了一个包含数据成员(字段)和函数成员(方法、属性等)的数据结构。
类类型支持继承和多态,这些是派生类可用来扩展和专用化基类的一种机制。
结构类型与类类型相似,表示一个带有数据成员和函数成员的结构。
但是,与类不同,结构是一种值类型,并且不需要堆分配。
结构类型不支持用户指定的继承,并且所有结构类型都隐式地从类型object继承。
接口类型定义了一个协定,作为一个函数成员的命名集合。
实现某个接口的类或结构必须提供该接口的函数成员的实现。
一个接口可以从多个基接口继承,而一个类或结构可以实现多个接口。
枚举类型是具有命名常量的独特的类型。
每种枚举类型都具有一个基础类型,该基础类型必须是八种整型之一。
枚举类型的值集和它的基础类型的值集相同。
委托类型表示对具有特定参数列表和返回类型的方法的引用。
通过委托,我们能够将方法作为实体赋值给变量和作为参数传递。
委托类似于在其他某些语言中的函数指针的概念,但是与函数指针不同,委托是面向对象的,并且是类型安全的。
C#支持由任何类型组成的一维和多维数组。
与其他类型不同,数组类型不必在使用之前事先声明。
实际上,数组类型是通过在某个类型名后加一对方括号来构造的。
例如,int[]是一维int数组,int[,]是二维int数组,int[][]是一维int数组的一维数组。
C#的类型系统是统一的,因此任何类型的值都可以按对象处理。
C#中的每个类型直接或间接地从object类类型派生,而object是所有类型的最终基类。
引用类型的值都被当作“对象”来处理,这是因为这些值可以简单地被视为是属于object类型。
值类型的值则通过执行装箱(boxing)和拆箱(unboxing)操作亦按对象处理。
下面的示例将int值转换为object,然后又转换回int。
usingSystem;
classTest
{
staticvoidMain(){
inti=123;
objecto=i;//Boxing
intj=(int)o;//Unboxing
}
}
当将值类型的值转换为类型object时,将分配一个对象实例(也称为“箱子”)以包含该值,并将值复制到该箱子中。
反过来,当将一个object引用强制转换为值类型时,将检查所引用的对象是否含有正确的值类型,如果是,则将箱子中的值复制出来。
C#的统一类型系统实际上意味着值类型可以“按需”转换为对象。
由于这种统一性,使用object类型的通用库(例如.NETFramework中的集合类)既可以用于引用类型,又可以用于值类型。
C#中存在几种变量(variable),包括字段、数组元素、局部变量和参数。
变量表示了存储位置,并且每个变量都有一个类型,以决定什么样的值能够存入变量,如下表所示。
变量类型
可能的内容
值类型
类型完全相同的值
object
空引用、对任何引用类型的对象的引用,或对任何值类型的装箱值的引用
类类型
空引用、对该类类型的实例的引用,或者对从该类类型派生的类的实例的引用
接口类型
空引用、对实现该接口类型的类类型的实例的引用,或者对实现该接口类型的值类型的装箱值的引用
数组类型
空引用、对该数组类型的实例的引用,或者对兼容数组类型的实例的引用
委托类型
空引用或对该委托类型的实例的引用
1.4表达式
表达式(expression)由操作数(operand)和运算符(operator)构成。
表达式的运算符指示对操作数进行什么样的运算。
运算符的示例包括+、-、*、/和new。
操作数的示例包括文本(literal)、字段、局部变量和表达式。
当表达式包含多个运算符时,运算符的优先级(precedence)控制各运算符的计算顺序。
例如,表达式x+y*z按x+(y*z)计算,因为*运算符的优先级高于+运算符。
大多数运算符都可以重载(overload)。
运算符重载允许指定用户定义的运算符实现来执行运算,这些运算的操作数中至少有一个,甚至所有都属于用户定义的类类型或结构类型。
下表总结了C#运算符,并按优先级从高到低的顺序列出各运算符类别。
同一类别中的运算符优先级相同。
类别
表达式
说明
基本
x.m
成员访问
x(...)
方法和委托调用
x[...]
数组和索引器访问
x++
后增量
x--
后减量
newT(...)
对象和委托创建
newT[...]
数组创建
typeof(T)
获得T的System.Type对象
checked(x)
在checked上下文中计算表达式
unchecked(x)
在unchecked上下文中计算表达式
一元
+x
表达式的值相同
-x
求相反数
!
x
逻辑求反
~x
按位求反
++x
前增量
--x
前减量
(T)x
显式将x转换为类型T
乘除
x*y
乘法
x/y
除法
x%y
求余
加减
x+y
加法、字符串串联、委托组合
x–y
减法、委托移除
移位
x< 左移 x>>y 右移 关系和类型检测 x 小于 x>y 大于 x<=y 小于或等于 x>=y 大于或等于 xisT 如果x属于T类型,则返回true,否则返回false xasT 返回转换为类型T的x,如果x不是T则返回null 相等 x==y 等于 x! =y 不等于 逻辑AND x&y 整型按位AND,布尔逻辑AND 逻辑XOR x^y 整型按位XOR,布尔逻辑XOR 逻辑OR x|y 整型按位OR,布尔逻辑OR 条件AND x&&y 仅当x为true才对y求值 条件OR x||y 仅当x为false才对y求值 条件 x? y: z 如果x为true,则对y求值,如果x为false,则对z求值 赋值 x=y 赋值 xop=y 复合赋值;支持的运算符有: *=/=%=+=-=<<=>>=&=^=|= 1.5语句 程序的操作是使用语句(statement)来表示的。 C#支持几种不同的语句,其中许多以嵌入语句的形式定义。 块(block)用于在只允许使用单个语句的上下文中编写多条语句。 块由位于一对大括号{和}之间的语句列表组成。 声明语句(declarationstatement)用于声明局部变量和常量。 表达式语句(expressionstatement)用于对表达式求值。 可用作语句的表达式包括方法调用、使用new运算符的对象分配、使用=和复合赋值运算符的赋值,以及使用++和--运算符的增量和减量运算。 选择语句(selectionstatement)用于根据表达式的值从若干个给定的语句中选择一个来执行。 这一组语句有if和switch语句。 迭代语句(iterationstatement)用于重复执行嵌入语句。 这一组语句有while、do、for和foreach语句。 跳转语句(jumpstatement)用于转移控制。 这一组语句有break、continue、goto、throw和return语句。 try...catch语句用于捕获在块的执行期间发生的异常,try...finally语句用于指定终止代码,不管是否发生异常,该代码都始终要执行。 checked语句和unchecked语句用于控制整型算术运算和转换的溢出检查上下文。 lock语句用于获取某个给定对象的互斥锁,执行一个语句,然后释放该锁。 using语句用于获得一个资源,执行一个语句,然后释放该资源。 下表列出了C#的各语句,并提供每个语句的示例。 语句 示例 局部变量声明 staticvoidMain(){ inta; intb=2,c=3; a=1; Console.WriteLine(a+b+c); } 局部常量声明 staticvoidMain(){ constfloatpi=3.1415927f; constintr=25; Console.WriteLine(pi*r*r); } 表达式语句 staticvoidMain(){ inti; i=123;//Expressionstatement
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 01 C# 程序结构和数据类型 程序结构 数据类型