标签:
C#类型的取值范围
名称 | CTS类型 | 说明 | 范围 |
---|---|---|---|
sbyte | System.SByte | 8位有符号的整数 | -128~127(−27−27~27−127−1) |
short | System.Int16 | 16位有符号的整数 | -32 768~32 767(−215−215~215−1215−1) |
int | System.Int32 | 32位有符号的整数 | -2 147 483 648~2 147 483 647(−231−231~231−1231−1) |
long | System.Int64 | 64位有符号的整数 | −263−263~263−1263−1 |
byte | System.Byte | 8位无符号的整数 | 0~255(0~28−128−1) |
ushort | System.UInt16 | 16位无符号的整数 | 0~65535(0~216−1216−1) |
uint | System.UInt32 | 32位无符号的整数 | 0~4 294 967 295(0~232−1232−1) |
ulong | System.UInt64 | 64位无符号的整数 | 0~18 446 744 073 709 551 615(0~264−1264−1) |
访问限制符
修饰符 | 应用于 | 说明 |
---|---|---|
public | 所有类型或成员 | 任何代码均可以访问该项 |
protected | 类型和内嵌类型的所有成员 | 只有派生的类型能够访问该项 |
internal | 所有类型或成员 | 只能在包含它的程序集中访问该项 |
private | 类型和内嵌类型的所有成员 | 只能在它所属的类型中访问该项 |
protected internal | 类型和内嵌类型的所有成员 | 只能在包含它的程序集和派生类型的任何代码中访问该项 |
C#常见的修饰符
修饰符 | 应用于 | 说明 |
---|---|---|
new | 函数成员 | 成员用相同的签名隐藏继承的成员 |
static | 所有成员 | 成员不作用于类的具体实例 |
virtual | 仅函数成员 | 成员可以由派生类重写 |
abstract | 仅函数成员 | 虚拟成员定义了成员的签名,但没有提供实现代码 |
override | 仅函数成员 | 成员重写了继承的虚拟或抽象成员 |
sealed | 类、方法和属性 | 对于类,不能继承自密封类。对于属性和方法,成员重写已继承的虚拟成员,但任何派生类中的任何成员都不能重写该成员。该修饰符必须与override一起使用 |
extern | 仅静态[DllImport]方法 | 成员在外部用另一种语言实现 |
结构体
new
运算符与类和其他引用类型的工作方式不同。new
运算符并不分配堆中的内存,而是只调用相应的构造函数,根据传送给它的参数初始化所有的字段。new
运算符,或者给所有的字段分别赋值,结构就完全初始化了。当然,如果结构定义为类的成员字段,在初始化包含的对象时,该结构会自动初始化为0。System.Object
。因此,结构也可以访问System.Object
的方法。在结构中,甚至可以重写System.Object
中的方法————如重写ToString()
方法。结构的继承链是:每个结构派生自System.ValueType
类,System.ValueType
类又派生自System.Object
。ValueType
并没有给Object
添加任何新成员,但提供了一些更适合结构的实现方式。注意,不能为结构提供其他基类,每个结构都派生自ValueType
。null
,且总是隐式地给出,即使提供了其他带参数的构造函数,也是如此。提供字段的初始值也不能绕过默认构造函数。扩展方法
this
关键字的后面。var
关键字。编译器可以根据变量的初始化值“推断 ” 变量的类型。使用var关键字需要遵循的一些规则:
密封类和密封方法
sealed
。对于类,这表示不能继承该类;对于方法,这表示不能重写该方法。sealed
时,最可能的情形是:如果要对库、类或自己编写的其他类作用域之外的类或方法进行操作,则重写某些功能会导致代码混乱。也可以因商业原因把类或方法标记为sealed
,以防第三方以违反授权协议的方式扩展该类。但一般情况下,在把类或成员标记为sealed
时要小心,因为这么做会严重限制它的使用方式。即使认为它不能对继承自一个类或重写类的某个成员发挥作用,仍有可能在将来的某个时刻,有人会遇到我们没有预料到的情形,此时这么做就很有用。.Net基类库大量使用了密封类 ,使希望从这些类中派生出自己的类的第三方开发人员无法访问这些类。例如,string
就是一个密封类。约束
约束 | 说明 |
---|---|
where T : struct | 对于结构约束,类型T必须是值类型 |
where T : class | 类约束指定类型T必须是引用类型 |
where T : IFoo | 指定类型T必须实现接口IFoo |
where T : Foo | 指定类型T必须派生自基类Foo |
where T : new() | 这是一个构造函数约束,指定类型T必须有一个默认构造函数 |
where T1 : T2 | 这个约束也可以指定类型T1派生自泛型类型T2。该约束也称为裸类型约束 |
where
子句的一个重要限制是,不能定义必须由泛型类型实现的运算符。运算符不能再借口中定义。在where
子句中,只能定义基类、接口和默认构造函数。复制数组
Array
类使用QuickSort
算法对数组中的元素进行排序。Array
类中的Sort()方法需要数组中的元素实现IComparable
接口。简单类型(如System.String和System.Int32)已经实现了IComparable接口。
元组
.NET 4
定义了8个泛型Tuple
类和一个静态Tuple
类,不同泛型Tuple
类支持不同数量的元素。例如,Tuple<T1>
包含一个元素,Tuple<T1, T2>
包含两个元素,以此类推。代码示例:
1 public class TupleExample 2 { 3 static void Main() 4 { 5 TupleExample example = new TupleExample(); 6 var result = example.Divide(5, 2); 7 Console.WriteLine("result of division: {0}, reminder: {1}", result.Item1, result.Item2); 8 } 9 10 public static Tuple<int, int> Divide(int dividend, int divisor) 11 { 12 int result = dividend / divisor; 13 int reminder = dividend % divisor; 14 15 return TupleExample.Create<int, int>(result, reminder); 16 } 17 }
如果元组包含项超过8个,就可以使用带8个参数的Tuple类定义。最后一个模板参数是TRest,表示必须给它传递一个元组,这样就可以创建带任意个参数的元组了。示例:
1 var tuple = Tuple.Create<string, string, string, int, int, int, double, Tuple<int, int>>("Stephanie", "Alina", "Nagel", 2009, 6, 2, 1.37, Tuple.Create<int, int>(52, 3490));
运算符
is
运算符:可以检查对象是否与特定的类型兼容。“兼容”表示对象是该类型或者派生自该类型。as
运算符:用于执行引用类型的显示类型转换。如果要转换的类型与制定的类型兼容,转换就会成功进行;如果类型不兼容,as
运算符就会返回null
值。sizeof
运算符:使用该运算符可以确定栈中值类型需要的长度(单位是字节);如果对于复杂类型(和非基元类型)使用该运算符,就需要把代码写在unsafe
块中,如:unsafe{Console.WriteLine(sizeof(Customer));}
null
,其结果就是null
。如: int? a = null;
int? b = a + 4; // b = null
int? c = a * 5; // c = null
null
可能的值。这个运算符放在两个操作数之间,第一个操作数必须是一个可空类型或者引用类型;第二个操作数必须与第一个操作数的类型相同,或者可以隐含地转换为第一个操作数的类型。比较引用类型的相等性
true
,否则返回false
。但是它认为null
等于null
。另外,该方法在应用于值类型时,它总是返回false,因为为了调用这个方法,值类型需要装箱到对象中。System.Object
实现代码也可以比较引用。但因为这个方法是虚拟的,所以可以在自己的类中重写它,从而按值来比较对象。特别是如果希望类的实例用作字典中的键,就需要重写这个方法,以比较相关值。否则,根据重写Object.GetHashCode()
的方式,包含对象的字典类要么不工作,要么工作的效率非常低。在重写Equals()方法时要注意,重写的代码不会抛出异常。同理,这是因为如果抛出异常,字典类就会出问题,一些在内部调用这个方法的.NET
基类也可能出问题。null
的情况,因此,如果一个对象可能是null
,这个方法就可以抛出异常,提供额外保护。静态重载版本首先要检查它传递的引用是否为null
。如果他们都是null
,就返回true
(因为null
与null
相等)。如果只有一个引用是null
,就返回false
。如果两个引用实际上引用了某个对象,它就调用Equals()的虚拟实例版本。这表示在重写Equals()的实例版本时,其效果相当于也重写了静态版本。bool b = (x == y);// x, y object references
运算符重载
operator
关键字告诉编译器,它实际上是一个自定义的运算符重载,后面是相关运算符的实际符号,返回类型是在使用这个运算符时获得的类型。+
和-
运算符,第一个参数是运算符左边的值,第二个参数是运算符右边的值。lhs
,运算符右边的参数命名为rhs
。public
和static
,这表示它们与它们的类或结构相关联,而不是与某个特定实例相关联,所以运算符重载的代码体不能访问非静态类成员,也不能访问this
标识符。==
,也就必须重载!=
;否则会产生编译错误。另外,比较运算符必须返回布尔类型的值。这是它们与算术运算符的根本区别。==
和!=
时,还必须重载从System.Object
中继承的Equals()和GetHashCode()方法,否则会产生一个编译警告。原因是Equals()方法应实现与==
运算符相同类型的相等逻辑。委托
Action
Action
是无返回值的泛型委托。Action
表示无参,无返回值的委托Action<int,string>
表示有传入参数int
,string
无返回值的委托Action<int,string,bool>
表示有传入参数int
,string
,bool
无返回值的委托Action<int,int,int,int>
表示有传入4个int
型参数,无返回值的委托Action
至少0个参数,至多16个参数,无返回值。Func
Func
是有返回值的泛型委托Func<int>
表示无参,返回值为int的委托Func<object,string,int>
表示传入参数为object
, string
返回值为int的委托Func<object,string,int>
表示传入参数为object
, string
返回值为int的委托Func<T1,T2,,T3,int>
表示传入参数为T1
,T2
,T3
(泛型)返回值为int
的委托Func
至少0个参数,至多16个参数,根据返回值泛型返回。必须有返回值,不可void
Lambda
表达式
Lambda
表达式。或者说Lambda
表达式可以用于类型是一个委托的任意地方。Lambda
表达式只有一条语句,在方法块内就不需要花括号和return
语句,因为编译器会添加一条隐式return
语句。正则表达式
符 号 | 含 义 | 示 例 | 匹配的示例 |
---|---|---|---|
^ | 输入文本的开头 | ^B | B,但只能是文本中的第一个字符 |
$ | 输入文本的结尾 | X$ | X,但只能是文本中的最后一个字符 |
. | 除了换行符(\n)以外的所有单个字符 | i.ation | isation、ization |
* | 可以重复0次或多次的前导字符 | ra*t | rt、rat、raat和raaat等 |
+ | 可以重复1次或多次的前导字符 | ra+t | rat、raat和raaat等(但不能是rt) |
? | 可以重复0次或1次的前导字符 | ra?t | 只有rt和rat匹配 |
\s | 任何空白字符 | \sa | [space]a、\ta、\na(其中[space]表示空格,\t和\n都是转移字符) |
\S | 任何不是空白的字符 | \SF | aF、rF、cF,但不能是\tF |
\b | 字边界 | ion\b | 以ion结尾的任何字 |
\B | 不是字边界的任意位置 | \BX\B | 字中间的任何X |
[1|c]
表示字符可以是1
或c
。在方括号中,也可以指定一个范围,例如[a-z]
表示所有的小写字母,[A-E]
表示A
~E
之间的所有大写字母(包括字母A
和E
),[0-9]
表示一个数字。如果要搜索一个整数,就可以编写[0-9]+
。集合
LinkedList<T>
是一个双向链表,其元素指向它前面和后面的元素。其特点是:插入快,查找慢。SortedList<TKey,TValue>
类,这个类按照键给元素排序。List<T>
类,但没有在内存中移动后续元素的性能开销。int
由字典用于计算在对应位置放置元素的索引。IEquatable<T>.Equals()
方法,或重写Object
类的Equals()方法。因为不同的键对象可能返回相同的散列代码,所以字典使用Equals()方法来比较键。GetHashCode()方法的实现代码必须满足如下要求:
int
可以存储的整个数字范围上。如果为Equals()方法提供了重写版本,但没有提供GetHashCode()方法的重写版本,C#编译器就会显示一个编译警告。
LINQ
from
子句开头,以select
或group
子句结束。在这两个子句之间,可以使用where
、orderby
、join
、let
和其他from
子句。LINQ
为IEnumerable<T>
接口提供了各种扩展方法,以便用户在实现了该接口的任意集合上使用LINQ
查询。释放非托管的资源
System.IDisposable
接口。析构函数
IDisposable接口
System.IDisposable
接口替代析构函数。IDisposable
接口定义了一种模式(具有语言级的支持),该模式为释放非托管的资源提供了确定的机制,并避免产生析构函数固有的与垃圾回收器相关的问题。IDisposable
接口声明了一个Dispos()方法,它不带参数,返回void
。IDisposable
接口的封装对象上调用Dispose()方法。这样,Dispose()方法为何时释放非托管资源提供了精确的控制。以上是《C#高级编程》前二十章的读书笔记。笔记摘录了笔者认为易忘的知识点,方便以后查阅和复习。摘抄整理过程中难免疏忽和遗漏,如有错误不当之处,请不吝指出,在此感激不尽!
声明:本文欢迎转载和分享,但是请尊重作者的劳动成果,转载分享时请注明出处:http://www.cnblogs.com/davidsheh/p/5236686.html 。同时,码字实在不易,如果你觉得笔者分享的笔记对你有点用处,请顺手点击下方的推荐,谢谢!
标签:
原文地址:http://www.cnblogs.com/davidsheh/p/5236686.html