C#数据类型

一、数据类型

基本数据类型:C#拥有比C/C++或者Java更广泛的数据类型.这些类型是bool、byte、sbyte、short、ushort、int、uint、long、ulong、float、double和decimal,像Java一样,所有这些类型都有一个固定的大小.又像C和C++一样,每个数据类型都有有符号和无符号两种类型.与Java相同的是,一个字符变量包含的是一个16位的Unicode字符,C#新的数据类型是decimal数据类型,对于货币数据,它能存放28位10进制数字。

两个基本类:一个名叫object的类是所有其他类的基类。而一个名叫string的类也象object一样是这个语言的一部分.作为语言的一部分存在意味着编译器有可能使用它,无论何时在程序中写入一句带引号的字符串,编译器会创建一个string对象来保存它。

参数传递:方法可以被声明接受可变数目的参数.缺省的参数传递方法是对基本数据类型进行值传递。ref关键字可以用来强迫一个变量通过引用传递,这使得一个变量可以接受一个返回值。out关键字也能声明引用传递过程,与ref不同的地方是,它指明这个参数并不需要初始值。

COM的集成:C#对Windows程序最大的卖点可能就是它与COM的无缝集成了,COM就是微软的Win32组件技术.实际上,最终有可能在任何.NET语言里编写COM客户和服务器端。C#编写的类可以子类化一个已存在的COM组件;生成的类也能被作为一个COM组件使用,然后又能使用,比方说,JScript语言子类化它从而得到第三个COM组件。这种现象的结果是导致了一个运行环境的产生,在这个环境里的组件是网络服务,可用任何.NET语言子类化。

索引下标:一个索引属性除了不使用属性名来引用类成员而是用一个方括号中的数字来匿名引用(就象用数组下标一样)以外是相似的。

代理和反馈:一个代理对象包括了访问一个特定对象的特定方法所需的信息.只要把它当成一个聪明的方法指针就行了。代理对象可以被移动到另一个地方,然后可以通过访问它来对已存在的方法进行类型安全的调用.一个反馈方法是代理的特例.event关键字用在将在事件发生的时候被当成代理调用的方法声明中。

二、关键字

abstract as base bool break byte case catch char checked
decimal default delegate continue double do else enum event explicit
finally fixed float for foreach get goto if implicit const
in int interface internal is lock long new null object
partial out namespace override private ref readonly public return protected
short set stackalloc sizeof static this struct throw try switch
typeof uint unchecked ulong unsafe void ushort using value virtual
volatile where while yield class true extern false sbyte sealed [18]

部分描述:

abstract:可以和类、方法、属性、索引器及事件一起使用,标识一个可以扩展但不能被实体化的、必须被实现的类或方法。

as:一个转换操作符,如果转换失败,就返回null。

base:用于访问被派生类或构造中的同名成员隐藏的基类成员。

catch:定义一个代码块,在特定类型异常抛出时,执行块内代码。

checked:既是操作符又是语句,确保编译器运行时,检查整数类型操作或转换时出现的溢出。

const:标识一个可在编译时计算出来的变量值,即一经指派不可修改的值。

delegate:指定一个声明为一种委托类型。委托把方法封装为可调用实体,能在委托实体中调用。

enum:表示一个已命名常量群集的值类型。

event:允许一个类或对象提供通知的成员,他必须是委托类型。

explicit:一个定义用户自定义转换操作符的操作符,通常用来将内建类型转换为用户定义类型或反向操作,必须再转换时调用显示转换操作符。

extern:标识一个将在外部(通常不是c#语言)实现的方法。

finally:定义一个代码块,在程序控制离开try代码块后执行。参见try和catch。

fixed:在一个代码块执行时,在固定内存位置为一个变量指派一个指针。

foreach:用于遍历一个群集的元素。

goto:一个跳转语句,将程序执行重定向到一个标签语句。

implicit:一个操作符,定义一个用户定义的转换操作符,通常用来将预定义类型转换为用户定义类型或反向操作,隐式转换操作符必须在转换时使用。

interface:将一个声明指定为接口类型,即实现类或构造必须遵循的合同。

internal:一个访问修饰符。

namespace:定义一个逻辑组的类型和命名空间。

operator:用来声明或多载一个操作符。

out:标识一个参数值会受影响的参数,但在传入方法时,该参数无需先初始化。

params:声明一个参数数组。如果使用,必须修改指定的最后一个参数,允许可选参数。

readonly:标识一个变量的值在初始化后不可修改。

ref:标识一个参数值可能会受影响的参数。

sealed:防止类型被派生,防止方法和property被覆载。

sizeof:一个操作符,以byte为单位返回一个值类型的长度。

stackalloc:返回在堆上分配的一个内存块的指针。

struct:是一种值类型,可以声明常量、字段、方法、property、索引器、操作符、构造器和内嵌类型。

throw:抛出一个异常。

try:异常处理代码块的组成部分之一。try代码块包括可能会,抛出异常的代码。参阅catch和finally关键字。

typeof:一个操作符,返回传入参数的类型。

unchecked:禁止溢出检查。

unsafe:标注包含指针操作的代码块、方法或类。

using:当用于命名空间时,using关键字允许访问该命名空间中的类型,而无需指定其全名。也用于定义finalization操作的范围。

virtual:一个方法修饰符,标识可被覆载的方法。

volatile:标识一个可被操作系统、某些硬件设备或并发线程修改的attribute。

三、String类型常用方法

1、字符串的复制:

(1)、String.Copy(str):参数str为要复制的字符串,它回返回一个与该字符串相等的字符串

(2)、SreStr.CopyTo(StartOfSreStr, DestStr, StartOfDestStr, CopyLen):它必须被要复制的字符串实例调用,它可以实现复制其中某一部分到目标字符串的指定位置

2、字符串的比较:

String类字符串比较大概有4种方法:Compare(),CompareTo(), CompareOrdinal()和Equals(). Compare()方法是CompareTo()的静态版本.而Equals()与”==”是等价的,只要使用”==”运算符,就会调用Equals()方法。CompareOrdinal()对两个字符串进行比较,不考虑本地化语言和文化。

(1)、String.Compara(str1, str2):

(2)、String.CompareTo(string value):该实例与value的值进行比较。返回:如果string大于value则返回1,如果string小于value则返回-1,如果两个相等则返回0。

(3)、String.CompareOrdinal(str1, str2):是将整个字符串每5个字符(10个字节)分成一组,然后逐个比较,找到第一个不相同的ASCII码后退出循环。并且求出两者的ASCII码的差。【我不明白为什么要实现的如此麻烦。但是在CLR via C#上有这样的话:这个方法比其他方法都要快。应该是有一定道理的吧。所以当我们比较大小的时候,尽量使用CompareOrdinal方法。】

(4)、String.Equals(string value):用于比较两个字符串是否相等。返回:如果和String相等则为true;否则为false。【由于是非安全代码的比较,所以效率要比我们用安全代码高得多】

3、字符串的查找:

(1)、String.Contains(Findstr):参数:Findstr为要查找的字符或字符串;功能:找指定字符串是否包含一个字串,返回值的boolean类型,即只有true和false。

(2)、String.IndexOf(Findstr):参数:Findstr为要查找的字符或字符串;功能:查找FindStr在字符串中第一次出现的位置,返回值为第一次出现的下标,没有找到则返回-1.

(3)、String.LastIndexOf(FindStr):参数:Findstr为要查找的字符或字符串;功能:查找FindStr在字符串中最后一次出现的位置,返回值为最后一次出现的下标,没有找到则返回-1。

(4)、String.IndexOf(Findstr)还有一个重载函数String.indexof(),它的用法如下:

1
nResult = str.IndexOf('e', 5, 4); //从前向后定位从第5位到第9位中'e'出现的位置; 

(5)、String.indexof():在字符串中从前向后定位字符和字符串;所有的返回值都是指在字符串的绝对位置,如为空则为-1 。

4、字符串的截取:

(1)、String.SubString(StartIndex):参数:StartIndex为要进行截取的开始下标;功能:保留字符串中下标从StartIndex开始后面的全部字符串。

(2)、String.SubString(StartIndex, Len):参数:StartIndex为要开始截取的下标,Len为要截取的长度;功能:保留字符串中下标从StartIndex开始后面的Len个长度的字符串。

5、字符串的分割:

String.Split(SplitCh):参数:SplitCh为分割的字符;功能:将字符串一SplitCh进行分割,它的返回值是一个字符串数组。

6、字符串的合并:

(1)、String.Concat(str1, str2, …., strn):将n个字符串连接,中间没有连接符

(2)、String.Join(SplitCh, array):参数:SplitCh为合并后的分隔符,array为要合并的字符串数组;功能:将字符串书组合并成一个字符串,每个元素之间用SplitCh隔开

7、字符串的替换:

String.Replace(SreStr, ChangeStr):参数:SreStr为要替换的原字符串,ChangeStr为用来替换的字符串。作用:用ChangeStr来替换字符串中的SreStr.

8、字符串的插入与填充:

(1)、String.Insert(index, str):index是需要插入的位置,str是要插入的字符;

(2)、String.PadRight(Len, ch):参数:Len为字符串的总长度,ch为用来填充的字符。作用:如果字符串上都不够Len,则在结尾用ch来填充

(3)、String.PadLeft(Len, ch):参数:Len为字符串的总长度,ch为用来填充的字符。作用:如果字符串上都不够Len,则在开始处用ch来填充

9、字符串的删除:

(1)、String.Trim():删除字符串中开始和结尾处的空格。

(2)、string.Trim(Param char[]):参数:char[]为想要去掉的字符数组。功能:去掉字符串开始处和结尾处char[]中的所有字符。

(4)、String.Remove(Start):Start为需要删除的起始位置,该方法是将位置后的所有字符全部删除

(5)、String.Remove(Start, Len):Len是指需要删除的长度,与上面格式不同的是它是从起始位置开始删除Len个字符

10、字符串的大小写转换:

(1)、String.ToLower():将字符串转化为小写形式

(2)、String.ToUpper():将字符串转换威大写形式

11、字符串拘留池机构

同一个程序中,即使将同一个字符串复值给多个字符串,系统就会多次分配内存空间,这样不仅浪费内存,也会影响系统性能,为此,.Net提出了字符串拘留池机制。

拘留池机制原理:

使用拘留池后,当CLR启动后,会在内部创建一个容器,该容器的键为字符串的内容,值则时字符串在托管堆上的引用。这样的话,每次需要分配一个新字符串对象时,在分配内存之前先会检测容器中是否包含了该字符串对象,存在则返回已经存在的字符串对象的引用,不存在的话才会新分配对象,把它添加到内部容器中,然后再返回该对象的引用。【如果用new分配一个字符串对象,字符串拘留池机制不会起作用】,原理如下图:

定义一个字符串s1 = “123”:

20200721101623890

如果此时在给s2也赋值123时,则s2字符串变量s2也指向字符串对象“123”:

20200721101623906

那么CLR保存的字符串拘留池的容器可以访问吗?结果是肯定哒,System.String类中提供了两个静态方法可以进行访问:

(1)、public static String Intern (String s):返回字符串s在字符串拘留池中对应的引用,如果该字符串不在字符串拘留池中,那么会新分配一个字符串对象并添加到字符串拘留池中同时返回该字符串的引用。

(2)、public static String IsInterned (String s): 功能与上个方法相似。只是当字符串s不在字符串拘留池中时,不会分配新的对象,并返回null。

拘留池机制缺点:

拘留池机制每次在分配内存之前,先回在容器内部查找该字符串是否存在,这样就导致,如果一个程序中字符串赋值或者重复读很低甚至没有重复时,字符串拘留池机制不仅不会洁身内存,相反会因为CLR额外的保留了一个存储字符串池的容器,并且在每次进行字符串赋值时都要额外的检查这个容器而带来负面影响。

四、double类型保留小数位

1、四舍五入

1
2
var a1 = Math.Round(3.1415926,3); //值为3.142
var a2 = Math.Round(3.1, 3);//值为3.1

2、直接截取

(1)、Math.Floor()方法

1
2
double a = 1.999999;
a = Math.Floor(a * 1000) / 1000;//截取小数点后三位

(2)、字符截断方法

1
2
3
4
double a = 1.999999;
string b = a.ToString();
b = b.Remove(b.IndexOf(".")+4);//截取小数点后三位
a = double.Parse(b);

3、进位截取

1
待更新...
1
待更新...