9.1 表达式
略
9.2 字面量
9.2.1 整数字面量
236 // 整型
236L // 长整型
236U // 无符号类型
236UL // 无符号长整型
0b11101100 // 二进制, 必须以 0b 或 0B 开头
0XEC // 十六进制,必须以 0x 或 0X 开头
9.2.2 实数字面量
有三种类型,float
,double
,decimal
,分别对应 32 位、64 位、128 位精度。
后缀分别是 F
、D
、M
(小写亦可)。
无后缀的实数字面量是double
。
9.2.3 字符字面量
略
9.2.4 字符串字面量
分为常规字符串字面量和逐字字符串字面量。
逐字字符串字面量:
- 以
@
作为前缀; - 转义序列不会被求值;
- 唯一例外是相邻的双引号会被解释为单个单引号。
9.3 求值顺序
P169 运算符优先级
运算符结合性:赋值和条件运算符右结合,其他二元运算符左结合。
9.4 简单算术运算符
加减乘除,略。
9.5 求余运算符
%
还可以用于实数,得到实余数。
9.6 关系比较运算符和相等比较运算符
注意:C# 中数字不具有布尔意义。
比较操作和相等性操作
- 对于大多数引用类型,只比较它们的引用,即浅比较:只要两个引用指向内存中相同的对象,它们就是相等的;
- 而对于
string
类型对象则是深比较:需要字符串的长度和内容完全一致才相等。 - 委托也是深比较,详见第 14 章。
9.7 递增运算符和递减运算符
略
9.8 条件逻辑运算符
注意||
和&&
中存在短路行为。
9.9 逻辑运算符(位运算)
略
9.10 移位运算符
略
9.11 赋值运算符
略
9.12 条件运算符
略
9.13 一元算术运算符
略
9.14 用户定义的类型转换
// 隐式转换的例子
public class LimitedInt
{
const int minVal = 0, maxVal = 100;
public int theValue;
// public static implicit 一定要有
public static implicit operator LimitedInt(int input)
{
LimitedInt ret = new LimitedInt();
if (input < minVal)
ret.theValue = 0;
else
ret.theValue = (input > maxVal ? maxVal : input);
return ret;
}
public static implicit operator int(LimitedInt input)
{
return input.theValue;
}
}
static void Main()
{
LimitedInt li = new LimitedInt();
li = 300;
int a = li;
Console.WriteLine("li.theValue = {0}, a = {1}", li.theValue, a);
}
C# 提供两种转换:
- 隐式转换:编译器会根据上下文自动执行;
- 显式转换:编译器只在使用显式转换运算符时才执行转换,只需把上个例子中的
implicit
改成explicit
,类型转换时加上运算符即可。
9.15 运算符重载
// 重载了运算符 ++,使其变为平方
public class MyInt
{
public int Value;
public static MyInt operator ++(MyInt x)
{
MyInt ret = new MyInt();
ret.Value = x.Value * x.Value;
return ret;
}
}
static void Main()
{
MyInt mi = new MyInt();
mi.Value = 5;
++mi;
Console.WriteLine("{0}", mi.Value);
}
9.15.2 运算符重载的限制
- 赋值运算符不能被重载;
- 重载不改变运算符的优先级、结合性、语法;
- 对于引用类型的后置递增递减操作,最后返回的是一开始的引用类型,所以不会返回其真正的起始状态。
9.16 typeof
运算符
using System;
using System.Reflection;
namespace Test
{
class Program
{
public class MyInt
{
public int Value;
}
static void Main()
{
Type t = typeof(MyInt);
FieldInfo[] fi = t.GetFields();
MethodInfo[] mi = t.GetMethods();
foreach (FieldInfo f in fi)
Console.WriteLine("Field: {0}", f.Name);
foreach (MethodInfo m in mi)
Console.WriteLine("Method: {0}", m.Name);
}
}
}
typeof
运算符返回已知类型的System.Type
对象,不能被重载。
9.17 nameof
运算符
返回一个表示传入参数的字符串。