C#学习心得Word下载.docx
《C#学习心得Word下载.docx》由会员分享,可在线阅读,更多相关《C#学习心得Word下载.docx(30页珍藏版)》请在冰点文库上搜索。
![C#学习心得Word下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/4/9137abaf-b721-422f-a1e9-475bd19bc743/9137abaf-b721-422f-a1e9-475bd19bc7431.gif)
Console、WriteLine("
HelloWorld"
);
}
}
在C#当中的每样东西都被封装到一个类中,C#的类又被封装到一个命名空间当中(就象一个文件夹中的文件)。
类似于C++,main方法就是您的程序的入口点。
C++的main函数调用名称就是"
main"
而C#的main函数就是以大写字母M为起点的名称就是"
Main"
。
没有必要把分号分隔符放在类语句块或者结构定义语句块后。
这在C++当中被要求,但在C#当中却不就是。
三、命名空间
每一个类都被包装进一个命名空间。
命名空间的概念与C++的完全相同,但在C#当中使用命名空间的频率较C++还高。
您可以使用点限定符(dotqulifier)访问一个类。
在上面的helloworld程序当中MyNameSpace就就是一个命名空间。
现在思考这样的一个问题,您想从某些别的类的命名空间当中来访问HelloWorld这个类该如何操作。
这有一个例子:
namespaceAnotherNameSpace
classAnotherClass
publicvoidFunc()
现在,从您的HelloWorld类里您能象这样去访问上面的这个AnotherNameSpace的命名空间:
usingAnotherNameSpace;
//youwilladdthisusingstatement
classHelloWorld
staticvoidMain(string[]args)
AnotherClassobj=newAnotherClass();
obj、Func();
在、NET库当中,System就是位于顶层的命名空间,别的命名空间都存在这个命名空间之下。
默认状态下,存在一个全局的命名空间,因此一个在命名空间外定义的类将直接在这个全局命名空间之下;
因此,您能在没有任何点限定符的情况下访问这个类。
四、变量
除以下区别外,C#当中的变量几乎与C++同:
与C++不同,C#变量被访问之前必须被初始化;
否则编译时会报错。
因此,访问一个未初始化变量就是不可能的事。
C#中您不会访问到一个不确定的指针。
(译者注:
严格说起来C#已经把指针概念异化,限制更严格。
所以有些资料上会说C#取消了指针概念)
一个超出数组边界的表达式就是不可访问的。
C#中没有全局(整个Application)的变量或全局函数,全局方式的操作就是通过静态函数与静态变量来实现的。
五、数据类型
所有C#数据类型都派生自基类Object。
这里有两类数据类型:
基本型/内置型用户自定义型
下面一个C#内置类型列表:
类型字节数解释
byte1无符号字节型
sbyte1有符号字节型
short2有符号短字节型
ushort2无符号短字节型
int4有符号整型
uint4无符号整型
long8有符号长整型
ulong8无符号长整型
float4浮点数
double8双精度数
decimal8固定精度数
stringunicode字串型
charunicode字符型
bool真假布尔型
注意:
C#当中的类型范围与C++有所不同;
例如,C++的long型就是4个字节,而在C#当中就是8个字节。
同样地,bool型与string型都不同于C++。
bool型只接受true与false两种值。
不接受任何整数类型。
用户定义类型包括:
类类型(class)
结构类型(struct)
接口类型(interface)
数据类型的内存分配形式的不同又把它们分成了两种类型:
值类型(ValueTypes)
引用类型(ReferenceTypes)
值类型:
值类型数据在栈中分配。
她们包括:
所有基本或内置类型(不包括string类型)、结构类型、枚举类型(enumtype)
引用类型:
引用类型在堆中分配,当它们不再被使用时将被垃圾收集。
它们使用new运算符来创建,对这些类型而言,不存在C++当中的delete操作符,根本不同于C++会显式使用delete这个运算符去释放创建的这个类型。
C#中,通过垃圾收集器,这些类型会自动被收集处理。
引用类型包括:
类类型、接口类型、象数组这样的集合类型类型、字串类型、枚举类型
枚举类型与C++当中的概念非常相似。
它们都通过一个enum关键字来定义。
示例:
enumWeekdays
Saturday,Sunday,Monday,Tuesday,Wednesday,Thursday,Friday
类类型与结构类型的比较
除了在内存分配形式上外,类与结构的概念完全与C++相同。
类的对象被分配在堆中,并且通过new来创建,结构也就是被new创建但却被分配在栈当中。
C#当中,结构型适于快速访问与拥有少量成员的数据类型。
如果涉及量较多,您应该创建一个类来实现她。
这与堆与栈内存分配结构的特点有关。
简而言之,栈就是一种顺序分配的内存;
堆就是不一定就是连续的内存空间。
具体内容需要大家参阅相关资料)
structDate
intday;
intmonth;
intyear;
classDate
stringweekday;
stringmonthName;
publicintGetDay()
returnday;
publicintGetMonth()
returnmonth;
publicintGetYear()
returnyear;
publicvoidSetDay(intDay)
day=Day;
publicvoidSetMonth(intMonth)
month=Month;
publicvoidSetYear(intYear)
year=Year;
publicboolIsLeapYear()
return(year/4==0);
publicvoidSetDate(intday,intmonth,intyear)
、、、
六、属性
如果您熟悉C++面象对象的方式,您就一定有一个属性的概念。
在上面示例当中,以C++的观点来瞧,Data类的属性就就是day、month与year。
用C#方式,您可以把它们写成Get与Set方法。
C#提供了一个更方便、简单、直接的方式来访问属性。
因此上面的类可以被写成:
publicintDay{
get{
set{
day=value;
publicintMonth{
month=value;
publicintYear{
year=value;
publicboolIsLeapYear(intyear)
returnyear%4==0?
true:
false;
this、day=day;
this、month=month;
this、year=year;
您可在这里得到并设置这些属性:
classUser
publicstaticvoidMain()
Datedate=newDate();
date、Day=27;
date、Month=6;
date、Year=2003;
Console、WriteLine("
Date:
{0}/{1}/{2}"
date、Day,
date、Month,
date、Year);
七、修饰符
您必须已经知道public、private、protected这些常在C++当中使用的修饰符。
这里我会讨论一些C#引入的新的修饰符。
readonly(只读)
readonly修饰符仅在类的数据成员中使用。
正如这名字所提示的,readonly数据成员仅能只读,它们只能在构造函数或就是直接初始化操作下赋值一次。
readonly与const数据成员不同,const要求您在声明中初始化,这就是直接进行的。
瞧下面的示例代码:
classMyClass
constintconstInt=100;
//直接初始化
readonlyintmyInt=5;
readonlyintmyInt2;
//译者注:
仅做声明,未做初始化
publicMyClass()
myInt2=8;
//间接的
publicFunc()
myInt=7;
//非法操作(译者注:
不得赋值两次)
Console、WriteLine(myInt2、ToString());
sealed(密封)
密封类不允许任何类继承,它没有派生类。
因此,您可以对您不想被继承的类使用sealed关键字。
sealedclassCanNotbeTheParent
inta=5;
unsafe(不安全)
您可使用unsafe修饰符来定义一个不安全的上下文。
在不安全的上下文里,您能写些如C++指针这样的不安全的代码。
publicunsafeMyFunction(int*pInt,double*pDouble)
int*pAnotherInt=newint;
*pAnotherInt=10;
pInt=pAnotherInt;
、、、
*pDouble=8、9;
八、interface(接口)
如果您有COM方面的概念,您会立亥明白我要谈论的内容。
一个接口就就是一个抽象的基类,这个基类仅仅包含功能描述,而这些功能的实现则由子类来完成。
C#中您要用interface关键字来定义象接口这样的类。
、NET就就是基于这样的接口上的。
C#中您不支持C++所允许的类多继承(译者注:
即一个派生类可以从两个或两个以上的父类中派生)。
但就是多继承方式可以通过接口获得。
也就就是说您的一个子类可以从多个接口中派生实现。
interfacemyDrawing
intoriginx
get;
set;
intoriginy
voidDraw(objectshape);
classShape:
myDrawing
intOriX;
intOriY;
publicintoriginx
get{
returnOriX;
set{
OriX=value;
publicintoriginy
returnOriY;
OriY=value;
publicvoidDraw(objectshape)
、、、//dosomething
//class'
sownmethod
publicvoidMoveShape(intnewX,intnewY)
、、、、、
九、Arrays(数组)
C#中的数组比C++的表现更好。
数组被分配在堆中,因此就是引用类型。
您不可能访问超出一个数组边界的元素。
因此,C#会防止这样类型的bug。
一些辅助方式可以循环依次访问数组元素的功能也被提供了,foreach就就是这样的一个语句。
与C++相比,C#在数组语法上的特点如下:
方括号被置于数据类型之后而不就是在变量名之后。
创建数组元素要使用new操作符。
C#支持一维、多维以及交错数组(数组中的数组)。
int[]array=newint[10];
//整型一维数组
for(inti=0;
i<
array、Length;
i++)
array[i]=i;
int[,]array2=newint[5,10];
//整型二维数组
array2[1,2]=5;
int[,,]array3=newint[5,10,5];
//整型的三维数组
array3[0,2,4]=9;
int[][]arrayOfarray==newint[2];
//整型交错数组(数组中的数组)
arrayOfarray[0]=newint[4];
arrayOfarray[0]=newint[]{1,2,15};
一十、索引器
索引器被用于写一个访问集合元素的方法,集合使用"
[]"
这样的直接方式,类似于数组。
您所要做的就就是列出访问实例或元素的索引清单。
类的属性带的就是输入参数,而索引器带的就是元素的索引表,除此而外,她们二者的语法相同。
CollectionBase就是一个制作集合的库类。
List就是一个protected型的CollectionBase成员,储存着集合清单列表。
classShapes:
CollectionBase
publicvoidadd(Shapeshp)
List、Add(shp);
//indexer
publicShapethis[intindex]
return(Shape)List[index];
List[index]=value;
一十一、装箱与拆箱操作(Boxing/Unboxing)
C#的装箱思想就是全新的。
上面提到过所有的数据类型,不论内置或用户自定义,全都从命名空间System的一个基类object派生出来。
因此把基本的或者原始类型转换成object类型被称做装箱,反之,这种方式的逆操作被称为拆箱。
classTest
staticvoidMain()
intmyInt=12;
objectobj=myInt;
//装箱
intmyInt2=(int)obj;
//拆箱
示例展示了装箱与拆箱操作。
一个整型值转换成object类型,然后又转换回整型。
当一个值类型的变量需要转换成引用类型时,一个object的箱子会被分配容纳这个值的空间,这个值会被复制进这个箱子。
拆箱与此相反,一个object箱子中的数据被转换成它的原始值类型时,这个值将被从箱中复制到适当的存储位置。
一十二、方法参数
C#中有三种类型的参数:
值参数/输入型参数
引用型参数/输入输出型参数
Out参数
如果您有COM接口与它的参数类型的概念,您会很容易理解C#参数类型。
值概念与C++相同。
所要传递的值会被复制到一个位置上并被传递给函数。
SetDay(5);
voidSetDay(intday)
、、、、
引用型参数/输入输出参数
C#中的引用参数既不就是C++中的指针也不就是引用操作符(&
)来传递的。
C#的引用型参数减少了出错的可能。
引用型参数也被称作输入输出参数,因为您传递了一个引用地址,因此您可以从函数中传递一个输入值并且可以获得一个输出值。
您不能把一个未经初始化的引用型参数传递给函数。
C#用ref这个关键字来声明引用型参数。
当您传递一个变量给函数要求的引用参数时必须使用一个ref关键字说明。
inta=5;
FunctionA(refa);
//要用ref声明变量,否则您会得到
//一个编译错误
Console、WriteLine(a);
//指向地址的值为20
voidFunctionA(refintVal)
intx=Val;
Val=x*4;
Out型参数仅仅从函数当中返回一个值。
不要求有输入值。
C#用关键字out来描声明这个参数
intVal;
GetNodeValue(Val);
boolGetNodeValue(outintVal)
Val=value;
returntrue;
可变数量的参数与数组
数组在C#当中就是通过关键字params来描述传递的。
作为数组类型的变量,您能传递任意数量的元素。
从下面示例中您可以理解的更好。
voidFunc(paramsint[]array)
numberofelements{0}"
array、Length);
Func();
//prints0
Func(5);
//prints1
Func(7,9);
//prints2
Func(newint[]{3,8,10});
//prints3
int[]array=newint[8]{1,3,4,5,5,6,7,5};
Func(array);
//prints8
一十三、运算符与表达式
运算符与表达式概念与C++完全相同。
但就是一些新的有用的运算符被填加了进来。
我将在这里讨论其中的某些部分。
is运算符
is运算符被用于检查操作数的类型就是否相同或者就是否可以转换。
is运算符在多态环境下特别有用。
它有两个操作数,运算结果就是一个布尔型。
瞧这个示例:
voidfunction(objectparam)
{
if(paramisClassA)
//dosomething
elseif(paramisMyStruct)
as运算符
as运算符检查操作数的类型就是否可被转换或者就是否相等(这些as通过is运算符来完成。
如果结果就是可转换的,则结果将被转换或者被装箱,成object(关于as运算符进行装箱成目标类型的操作请瞧前面的装箱/拆箱操作)。
如果不可转换或者装箱,则返回值就是null。
瞧一瞧下面的例子我们会更好地理解这个概念。
Shapeshp=newShape();
Vehicleveh=shpasVehicle;
//结果就是null,类型不可转换
Circlecir=newCircle();
Shapeshp=cir;
Circlecir2=shpasCircle;
//会被转换
object[]objects=newobject[2];
objects[0]="
Aisha"
;
object[1]=newShape();
stringstr;
for(inti=0;
i&
<
objects、Length;
i++)
str=objects[i]asstring;
if(str==null)
cannotbeconverted"
else
{0}"
str);
输出:
Aisha
cannotbeconverted
一十四、语句
除了对某些新增语句与对某些语句的修改以外,C#语句与C++非常相象。
下面就是新增的语句:
foreach
用于循环依次访问集合元素,比如象数组等。
foreach(stringsinarray)
Console、WriteLine(s);
lock
用于锁住代码块,使线程在临界争区内,别的线程无法进入锁定的临界区。
checked/unchecked
用于数值运算中的溢出检测。
intx=Int32、MaxValue;
x++;
//溢出检测
x++;
//异常
unchecked
//溢出}