基本的表达式、运算符、语句、转换在这就不过多介绍,有几个比较少见的就在这多提一嘴吧。

字符串字面量@

逐字字符串字面量以@字符为前缀,而且该字符串中的转义序列不会被求值。
逐字字符串字面量的唯一例外是相邻的双引号组会被解释成单个双引号字符

1
2
string vst1 = @"Hello world""";
string vst2 = @"H\tell\no\tworld""";

委托的比较

如果两个委托都是null,或两者的调用列表中有相同数目的成员,并且调用列表相匹配,那么比较返回true。

运算符重载

运算符重载不能创建新的运算符,不能改变运算符的语法,不能重新定义运算符如何处理预定义类型,不能改变运算符的优先级或结合性。
注意:对于引用类型的对象,前置操作没有问题,因为没有进行复制。但是对于后置操作,因为保存的副本是引用的副本,所以这意味着原始引用和引用副本指向相同的对象。

声明时必须使用public static。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Program {
static void Main(string[] args) {
LimitedInt limitedInt = new LimitedInt();
Console.WriteLine((limitedInt + 8).TheValue);
Console.WriteLine((-limitedInt).TheValue);
}
}
class LimitedInt {
public int TheValue = 20;
public static LimitedInt operator +(LimitedInt x,double y) {
LimitedInt li =new LimitedInt();
li.TheValue = x.TheValue + (int)y;
return li;
}
public static LimitedInt operator -(LimitedInt x) {
LimitedInt li = new LimitedInt();
li.TheValue = 0;
return li;
}
}

只可以为类和结构定义用户自定义转换,不能重定义标准隐式或显式转换。

源类型和目标类型必须是不同类型,且不能通过继承关联。

源类型和目标类型不能是接口类型或object类型。

转换运算符必须是源类型或目标类型的成员。

对于相同的源类型和目标类型不能声明隐式和显式转换。

using语句

某些类型的非托管对象有数量限制或很耗费系统资源,需要使用完尽快释放,using语言有助于简化该过程并确保这些资源被适当处理。
资源是指实现了System.IDisposable接口的类或结构,IDisposable接口含有单独一个名为Dispose的方法。
使用方式:

1
2
3
using(TextWriter tw = File.CreateText("Lincoln.txt")){
tw.WriteLine("Four score and seven years age...");
}

还可以用于相同的多个类型:

1
2
3
4
using(TextWriter tw = File.CreateText("Lincoln.txt"),
TextWriter tw = File.CreateText("Lincoln.txt")){
......
}

typeof运算符

typeof运算符返回作为其参数的任何类型的System.Type对象,可以理解成该实例对应类型的说明,Type类型是反射和依赖注入的基础,之后我会详细介绍。

is运算符

有些转换是不成功的,并且在运行时抛出InvalidCastException异常。可以用is运算符检查转换是否成功完成。

1
Expr is TargetType

返回布尔值,如果Expr可以通过引用转换、装箱、拆箱成功转换为目标值,则运算符返回true。

is运算符只可以用于引用转换以及装箱拆箱,不能用于用户自定义转换。

as运算符

as运算符和强制转换相似,只是它不抛出异常,如果转换失败,它返回null

1
Exper as TargetType

as运算符只可以用于引用转换以及装箱拆箱,不能用于用户自定义转换。

checked/unchecked语句和checked/unchecked运算符

check语句用来检查转换结果是否溢出,如果我们指定一个表达式或一个代码片段为checked,当转换产生溢出时会抛出OverflowException异常。

用法:

1
checked((int)3.14);
1
2
3
checked{
int a = 12.5;
}

用户定义类型转换

public和static是用户定义类型转换所必须的。
隐式转换(implicit):

1
2
3
4
5
6
7
8
9
10
11
class LimitedInt {
public int value;
public static implicit operator int (LimitedInt li) {//隐式转换LimitedInt——>int
return li.value;
}
public static implicit operator LimitedInt (int val) {//隐式转换int——>LimitedInt
LimitedInt li = new LimitedInt ();
li.value = val;
return li;
}
}

显式转换(explicit):

1
2
3
4
5
6
7
8
9
10
11
class LimitedInt {
public int value;
public static explicit operator int (LimitedInt li) {//显式转换LimitedInt——>int
return li.value;
}
public static explicit operator LimitedInt (int val) {//显式转换int——>LimitedInt
LimitedInt li = new LimitedInt ();
li.value = val;
return li;
}
}