C#学习总结.docx
- 文档编号:9538305
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:28
- 大小:107.55KB
C#学习总结.docx
《C#学习总结.docx》由会员分享,可在线阅读,更多相关《C#学习总结.docx(28页珍藏版)》请在冰豆网上搜索。
C#学习总结
关键字:
#region定义可扩展和收缩的代码的开头
关键字:
#endregion定义可扩展和收缩的代码的结尾
变量的命名:
第一个字符必须是字母、下划线或@(区别于C)
Hungarian记号法:
变量名前加小写,如iAge
PascalCase:
每个单词首字母大写
命名空间的两种约定(第一个字母大写)
(.NetFramework)
建议:
简单高级
CamelCase:
第一个单次首字母小写
(下划线字符变量名以及淘汰)
Console.ReadLine()提示用户输入信息,区别于java中的System.out,print();
Console.WriteLine()将结果打印出来,区别于java中的System.out,println();
Convert.toduble()把字符串转换为double类型;
Using语句可以应用到包含它们的命名空间;
C#与C++在switch语句中的一个主要区别是,在C++中,可以在运行完一个case语句后,运行另一个case语句,而C#不行,会通过break语句中断(但出现多个case语句堆叠,其后出现一行代码,实际上就是一次检查多个条件);
关键字:
const声明常量
Xxx.ToLower()把输入的字符或字符串转换成小写
问题console.write()与console.writeline()的区别?
解答:
每次输入一个字符时,console.write()不需要从一个新行开始,而console.writeline()就会从新的一行开始,也就是看输出是否需要换行而决定使用哪一个。
Break,continue,goto,return在处理控制循环时的区别:
Break——立即终止循环
continue——立即终止当前循环,继续执行下一次循环
goto——跳出循环,到标记的位置
return——跳出循环及其包含的参数
关键字checked
问题
溢出检查环境(什么区别)详见p76
关键字Unchecked
注:
使用convert转换时,他总是要进行溢出检查,checked和unchecked关键字以及项目属性设置没有什么作用。
关键字:
enum定义枚举,枚举使用一个基本类型来存储,默认为int,,每个值都会根据定义的顺序从0开始,每次加1,自动赋给对应的基本类型值;详见p81
for循环
使用区别(数组的数组应用foreach,详见p93)
foreach循环
把字符串前面的空格删掉
把字符串前面的空格删掉
注:
删掉字符串中的空格
在字符串左边添加空格,使字符串达到指定的长度
在字符串右边添加空格,使字符串达到指定的长度
把string转换为string数组,把它在制定的位置分隔开,这些位置采用char数组的形式
关键字:
params参数,某函数可以使用params关键字来定义
关键字:
ref
关键字:
out,指定所给的参数是一个输出参数,
问题注:
总结ref和out的使用说明以及在使用时的异同,详见p110
在运行期间把文本写入output窗口,只需调用下面的替代console.writeine()调用,就可以把文本写到希望的地方
Trace.WriteLine()没什么限制,可用于发布程序
问题使用这两个函数的好处
Debug.WriteLine()仅在调试模式下运行,甚至不能编译为可发布的程序,一旦使用该命令就会消失
注:
这两个函数的用法与console.writeine()的不同,其唯一的字符串参数用于输出消息,而不需要使用{x}语法插入变量值
Debug模式Debug.Write()
Console.Write()
Release模式Trace.Write()
Debug.WriteLineIf()
Trace.WriteLineIf()跟踪点
Debug.Writeif()
Trace.WriteIf()
Debug.Assert()带三个参数,布尔值、字符串
判定函数
Trace.Assert()带三个参数,布尔值、字符串
问题System.IndexOutOfRangeException详见P143
重点结构化异常处理语法:
try……catch……finally
注:
重点了解其语法以及熟练使用
关键字:
throw产生一个异常,需要把新初始化的异常作为其参数,产生一个异常,需要使用使用命名空间System的另一个异常System.Expection
例如throw(newSystem.Expection);
问题使用Trace.WriteLine()要优于使用Debug.WriteLine(),因为调试版本仅能用于调试程序,这个观点正确与否,怎么解释?
OPP技术
构造阶段—构造函数
对象的生命周期
析构阶段—析构函数(一般情况下,我们不依赖析构函数释放对象实例使用的资源)
关键字:
readonly表示这个字段只能在执行构造函数的过程中使用,或由初始化赋值语句赋值
public
关键字private
成员定义internal
protected
定义字段
virtual-----方法可以重写
关键字abstract-----必须在非抽象的派生类中重写(抽象类)
定义方法override-----重写了一个基类方法
external-----定义放在其他地方
get关键字/函数
(访问器)
定义属性
set关键字/函数------->value关键字赋值
重制成员:
使用工具修改代码,而不是手工修改,如将publicstringmystring----->privatestringmystring
关键字:
base表示包含在派生类中的基类的执行代码,类似于构造函数的控制(1,要对派生类的用户隐藏继承的公共成员,但任然能够在类中访问其功能;2,要给继承的虚拟成员添加执行代码,而不是简单是的重写的新执行代码替代它)
关键字:
this与base一样,this也可用在类成员的内部,且该关键字也引用对象实例,即是当前实例,this关键字最常见的功能就是把当期对象实例的引用传递给一个方法
循环冗余码校验(CRC校验):
循环冗余码校验是目前一种最常用的,也是最有效的差错检测编码。
对一个k比特的数据块(或称报文),发送方生成一个n比特的序列,称为帧检验序列(FCS),这个序列与原k比特的数据块组成一个长度为k+n比特的新序列(帧),如图10-2-2,一起发送。
当接收方收到这个k+n比特的帧后,进行校验。
这个特定的多项式称“生成多项式”。
发送方采用数据报文整除生成多项式,得到帧检验序列,附加到发送数据报文之后。
这个过程称为“生成”。
接收方,对接收到的报文用同样的生成多项式,再次进行整除,这个过程称为“校验”。
若除后余数为0(即能整除),表示接收的数据块正确,否则,表示接收数据有错。
上述CRC校验只能发现错误,而不能纠正错误。
CRC校验能够:
1)检查出全部一位错;
2)能检查出全部离散的二位错;
3)能检查出全部奇数个数错;
4)能检查出全部长度小于或等于n位的突发错(n为生成多项式的阶次);
5)能以1-(1/2)^(n-1)的概率检查出长度为n+1位的突发错。
例如,如果k=16,则该CRC校验码能全部检查出小于或等于16位长度的突发错,
并能以1-(1/2)^(n-1)=99.997%的概率检查出长度为17位的突发错,漏检概率为0.0003%。
因此CRC校验的校验效率很高,是现代通信技术中使用最多的方法。
要达到上述校验效率,生成多项式是关键。
常用的生成多项式有:
CRC-12P(x)=x^12+x^11+x^3+x^2+x^1+x^0
CRC-16P(x)=x^16+x^15+x^2+x^0
CRC-CCITTP(x)=x^16+x^12+x^5+x^0
CRC-32P(x)=x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0
CRC校验可用硬件电路实现,其逻辑如图10-2-3所示,其中相加点为异或逻辑,方框为移位寄存器,位数与帧检验序列相同。
CRC校验也可比照图10-2-3,采用软件实现。
其中多项式整除采用按位除(不带进位)。
即运算过程采用异或、移位操作完成。
用程序实现CRC校验序列的生成和CRC校验的过程如下:
CRC校验序列生成:
1.首先在数据报文后添入与帧检验序列位数相同个0。
从数据序列头部开始,与生成多项式进行异或运算。
2.根据数据序列最高位的状态,若为1,进行异或运算;若为0,不进行异或运算。
然后将整个数据报文(连同添加的0一起)左移一位,移出的数据自动丢失。
3.对剩余的报文继续执行第2步运算和左移过程,直到添加的0也经异或运算完成。
产生的余数即为生成的CRC校验码序列。
将它作为报文的添加字节,一起发送。
CRC校验的计算方法与生成过程中第2、3步相同,直到报文最后一位(连同发送端添加CRC校验码序列在内),若结果余数为0,表示正确,否则接收到的报文有错。
例10-2-1CRC校验过程
假定发送数据序列为:
1010001101,CRC生成多项式为:
P(x)=x^5+x^4+x^2+1=110101
发送数据序列*25:
101000110100000
运算:
101000110100000
⊕110101;最高位为1,进行异或运算
011101110100000
011101110100000;左移一位,首位0(斜体丢弃)
⊕110101;最高位为仍1,进行异或运算
00111010100000
00111010100000;左移一位,首位0(斜体丢弃)。
;最高位为0,不进行异或运算,
0111010100000;继续左移一位
⊕110101;最高位为1,进行异或运算
001111100000
001111100000;左移一位,首位0(斜体丢弃),再左移一位,首位0(斜体丢弃)
⊕110101
0010110000;同上连续左移二位
0010110000
⊕110101
01100100
01100100
⊕110101
0001110
0001110
将余数01110附在原数据序列中,得发送数据序列101000110101110
接收校验过程:
101000110101110101100110101110
⊕110101⊕110101
01110110110011
⊕110101⊕110101
00111010000110101
⊕110101⊕110101
0011111000000001110
⊕110101有差错
00101111
⊕110101
0110101
⊕110101
000000
没有差错
关键字:
base表示包含在派生类中得基类的执行代码(在控制构造函数时,用法相似)
接口成员的定义与类成员的定义的异同:
(1)不允许使用访问修饰符(如publiu、internal等),所有的接口成员都是公共的;
(2)
接口成员不能包含代码体什么意思?
(3)接口不能定义字段成员;
(4)接口成员不能用关键字static、virtual、abstract、sealed来定义;
(5)类型定义的成员是禁止的。
关键字:
new可以隐藏继承了基接口的成员,其执行方式与隐藏继承的类成员一样,在接口中的定义的属性可以确定访问块get和、或set中的哪一个不能用于该属性。
部分类的定义:
代码采用可以扩展和压缩的字段、属性、构造函数和方法,以便集中精力考虑自己感兴趣的内容;如采用#region。
。
。
。
。
。
。
。
#endregion(partialclassdefinition),应用于部分类的接口也会应用于整个类,因此每个部分类定义的文件中对类使用关键字partial;
扑克牌示例应用程序的步骤:
只读字段suit的容器
一、规划应程序Card类
类库(Lib)只读字段suit的容器
Deck类:
包含的若干对象,以及方法
添加Suit和Rank枚举>枚举成员
二、编写类库添加Card类>字段、方法、构造函数
(.cs)
添加Deck类>字段、方法、构造函数
三、类库的客户应用程序------>>添加类库项目
使用集合
定义集合
索引符------->>特殊类型的属性
给xxxLib添加集合
集合关键字值集合和IDictionary
迭代器
深度复制
给xxxLib添加深度复制
C#中的数组实现为System.Array类的实例,他只是集合类的一种,集合类一般用于处理对象列表,其功能比简单数组要多,这些功能是通过实现System.Collections命名空间中的接口而获得的,因此集合的的语法已经标准化。
关键字:
yield(查资料了解其用法)
封箱和装箱
类型比较
is运算符
比较运算符重载
值比较给xxxLib添加运算符重载
IComparable和IComparer接口
显式转换:
explicit关键字
重载转换运算符
转换隐式转换:
implicit关键字
把一种类型转换为指定的引用类型
as运算符
同类型、隐式转换、封箱
值类型:
大多数基本类型,例如int、double和所有的结构
引用类型:
string和所有的类
注:
值类型必须包含一个值,它可以在声明之后、赋值之前,在未赋值的状态下存在,但不能以任何方式使用。
而引用类型可以是null。
可空类型(nullabletype):
解决值类型的一个小问题
System.Nullable
nullableInt=null不能编译,应该这样:
nullableInt=newSystem.Nullable
可空类型的测试:
If(nullableInt==null){……..}等价于
f(nullableInt.HasValue){……..}
注:
上述测试方法不适用于引用类型,因为引用类型的变量值为null时就表示不存在对象,即使引用类型有一个HasValue属性。
可空类型的简化缩写:
int?
nullableInt;
如:
int?
op1=5;
Int?
result=op1*2;(intresult=op1*2会出现错误)
运算符:
int?
op1=null;(把5值赋给result)
Intresult=op1*2?
?
5;(?
?
自动转换类型)
∷运算符:
提供了访问命名空间中类型的另一种方式,即给出的命名空间别名优于一般的类型限定。
与global关键字一起使用,它实际上是顶级根命名空间的别名。
多态性:
多态性意味着有多重形式。
在面向对象编程范式中,多态性往往表现为"一个接口,多个功能"。
多态性可以是静态的或动态的。
在静态多态性中,函数的响应是在编译时发生的。
在动态多态性中,函数的响应是在运行时发生的。
静态多态性:
在编译时,函数和对象的连接机制被称为早期绑定,也被称为静态绑定。
C#提供了两种技术来实现静态多态性。
分别为:
(1)函数重载您可以在同一个范围内对相同的函数名有多个定义。
函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以是参数个数不同。
不能重载只有返回类型不同的函数声明。
(2)运算符重载可以重定义或重载C#中内置的运算符。
因此,程序员也可以使用用户自定义类型的运算符。
重载运算符是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的。
与其他函数一样,重载运算符有返回类型和参数列表 。
动态多态性:
C#允许您使用关键字 abstract 创建抽象类,用于提供接口的部分类的实现。
当一个派生类继承自该抽象类时,实现即完成。
抽象类包含抽象方法,抽象方法可被派生类实现。
派生类具有更专业的功能。
注:
下面是有关抽象类的一些规则:
您不能创建一个抽象类的实例。
您不能在一个抽象类外部声明一个抽象方法。
通过在类定义前面放置关键字 sealed,可以将类声明为密封类。
当一个类被声明为 sealed 时,它不能被继承。
抽象类不能被声明为sealed。
当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法。
虚方法是使用关键字 virtual 声明的。
虚方法可以在不同的继承类中有不同的实现。
对虚方法的调用是在运行时发生的。
动态多态性是通过 抽象类 和 虚方法 实现的。
接口(Interface):
接口定义了所有类继承接口时应遵循的语法合同。
接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。
(1)接口定义了属性、方法和事件,这些都是接口的成员。
(2)接口只包含了成员的声明。
成员的定义是派生类的责任。
接口提供了派生类应遵循的标准结构。
(3)抽象类在某种程度上与接口类似,但是,它们大多只是用在当只有少数方法由基类声明由派生类实现时。
(4)接口使用 interface 关键字声明,它与类的声明类似。
接口声明默认是public的。
反射(Reflection):
反射指程序可以访问、检测和修改它本身状态或行为的一种能力。
程序集包含模块,而模块包含类型,类型又包含成员。
反射则提供了封装程序集、模块和类型的对象。
可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。
然后,可以调用类型的方法或访问其字段和属性。
优缺点之优点:
1、反射提高了程序的灵活性和扩展性。
2、降低耦合性,提高自适应能力。
3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
优缺点之缺点:
1、性能问题:
使用发射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。
因此发射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。
反射(Reflection)的用途:
1、它允许在运行时查看属性(attribute)信息。
2、它允许审查集合中的各种类型,以及实例化这些类型。
3、它允许延迟绑定的方法和属性(property)。
4、它允许在运行时创建新类型,然后使用这些类型执行一些任务。
属性(Property):
是类(class)、结构(structure)和接口(interface)的命名(named)成员。
类或结构中的成员变量或方法称为 域(Field)。
属性(Property)是域(Field)的扩展,且可使用相同的语法来访问。
它们使用 访问器(accessors) 让私有域的值可被读写或操作。
注:
属性(Property)不会确定存储位置。
相反,它们具有可读写或计算它们值的 访问器(accessors)。
例如,有一个名为Student的类,带有age、name和code的私有域。
我们不能在类的范围以外直接访问这些域,但是我们可以拥有访问这些私有域的属性。
访问器(Accessors):
属性(Property)的访问器(accessor)包含有助于获取(读取或计算)或设置(写入)属性的可执行语句。
访问器(accessor)声明可包含一个get访问器、一个set访问器,或者同时包含二者。
索引器(Indexer):
允许一个对象可以像数组一样被索引。
当您为类定义一个索引器时,该类的行为就会像一个 虚拟数组(virtualarray) 一样。
您可以使用数组访问运算符([])来访问该类的实例。
索引器(Indexer)的用途:
索引器的行为的声明在某种程度上类似于属性(property)。
就像属性(property),您可使用 get 和 set 访问器来定义索引器。
但是,属性返回或设置一个特定的数据成员,而索引器返回或设置对象实例的一个特定值。
换句话说,它把实例数据分为更小的部分,并索引每个部分,获取或设置每个部分。
定义一个属性(property)包括提供属性名称。
索引器定义的时候不带有名称,但带有 this 关键字,它指向对象实例。
重载索引器(Indexer):
索引器(Indexer)可被重载。
索引器声明的时候也可带有多个参数,且每个参数可以是不同的类型。
没有必要让索引器必须是整型的。
C#允许索引器可以是其他类型。
委托(Delegate):
C#中的委托(Delegate)类似于C或C++中函数的指针。
委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。
引用可在运行时被改变。
注:
委托(Delegate)特别用于实现事件和回调方法。
所有的委托(Delegate)都派生自 System.Delegate 类。
声明委托(Delegate):
委托声明决定了可由该委托引用的方法。
委托可指向一个与其具有相同标签的方法。
实例化委托(Delegate):
一旦声明了委托类型,委托对象必须使用 new 关键字来创建,且与一个特定的方法有关。
当创建委托时,传递到 new 语句的参数就像方法调用一样书写,但是不带有参数。
委托的多播(MulticastingofaDelegate):
委托对象可使用"+"运算符进行合并。
一个合并委托调用它所合并的两个委托。
只有相同类型的委托可被合并。
"-"运算符可用于从合并的委托中移除组件委托。
使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。
这被称为委托的 多播(multicasting),也叫组播。
下面的程序演示了委托的多播:
usingSystem;
delegateintNumberChanger(intn);
namespaceDelegateAppl
{
classTestDelegate
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C# 学习 总结