运算符
三元运算符
if...else的简化形式,首先判断一个条件,如果为真,返回第一个值.为假返回后一个值
int a = 3; bool result = a > 10 ? true : false;//a>10?如果大于返回true否则返回false
checked和unchecked
如果把代码块标记为checked,CLR就会执行栈溢出检测
//byte类型最大取值255 byte a = 255; checked { a++; } //这里如果不加checed.++后输出0(不会抛异常,但会丢失数据,溢出的位会被舍弃,所以值为0),加上后会抛出栈溢出异常 Console.WriteLine(a);
如果要禁止栈溢出,则可以把代码标记unchecked
is运算符
is运算符可以检测对象是否与特定类型兼容,兼容表示对象是该类型或者派生自该类型(这里只是做说明没有实际意义,因为object是所有类型基类)
int i =10; i is object;
as运算符
//TODO
sizeof运算符
sizeof运算符可以确定栈中值类型需要的长度(单位为字节)
Console.WriteLine(sizeof(int));//4个字节 Console.WriteLine(sizeof(byte));//1个字节
typeof运算符
返回一个表示特定类型的Systen.Type对象
Console.WriteLine(typeof(int));//System.Int32 Console.WriteLine(typeof(byte));//System.Byte
可空类型和运算符
在C# 2.0中出现了可空类型,允许值类型也可以为空(null),可空类型的实现基于C#泛型。需要注意的是:在程序中使用可空类型就必须考虑null值在各种运算符一起使用的影响,通常可控类型与一元或二元运算符一起使用时,如果一个操作数为null或两个操作数为null.结果就是null
int? a = null; int? c = a + 4; //c=null
空合并运算符
空合并运算符??提供了快捷方式,处理可控类型和引用类型时表示null可能的值,需要注意:只能针对引用类型处理,规则是
- 如果第一个操作数不是null,值就等于第一个操作数的值
- 如果第一个操作数是null,值就等于第二个操作数的值
int? a = null; int b; b = a ?? 10;//第一个操作数是null,值为第二个操作数.10 a = 3; b = a ?? 10;//第一个操作数不是null,值为第一个操作数.3
类型安全性
隐式转换
隐式转换是系统默认的,不需要加以声明就会自动执行隐式类型转换,在隐式转换过程,编译器无需对转换进行详细检查就能够安全的执行.隐式类型转换是从低精度数值类型=>高精度数值类型
int a = 10; double b = a;//自动隐式类型转换
显式转换
将高精度值-->低精度进行数据转换时,可能会丢失数据,这时候需要使用显式转换,并且要考虑到可能出现算术溢出;显式转换需要用户明确指出指定要转换的类型
需要注意:
- 显式转换可能导致错误,进行这种转换时编译器会对转换进行溢出检测,如果有溢出说明转换失败,表示源类型不是一个合法的目标类型无法进行类型转换
- 强制类型转换会造成数据精度丢失
double a = 10; int b = (int)a;//显式将double类型转换为int
可空类型数据转换=>非可空类型或者另一个可空类型,其中可能会丢失数据,就必须使用显式类型转换,并且如果从可空类型转换为非可空类型时.且变量值为null.就会抛出InvalidOperationException异常
int? a = null; int b = (int)a; //System.InvalidOperationException:“可为空的对象必须具有一个值。
通过方法进行类型转换
ToString()方法:C#中的类型基类都继承自Object类,所以都可以使用ToString()来转换成字符串
int a = 10; string s = a.ToString();
int.Parse方法():int.Parse()用于将string类型参数转换为int,需要注意:string类型参数不能为null,并且也只能是各种整型,不能是浮点型
string a = "2"; string b = "2.6"; string c = null; int a1 = int.Parse(a);//正常 int a2 = int.Parse(b);//错误:输入字符串格式错误 int a3 = int.Parse(c);//值不能为null
int.TryParse方法():该方法int.Parse()方法类似,不同点在于int.Parse()方法无法转换成功时会抛出异常.而int.TryParse()方法在无法进行转换时会返回false,int.TryParse()方法需要一个out类型的参数,如果转换成功,out参数的值就是正常转换的值,否则,返回false
string a = "2"; string b = "2.6"; string c = null; int i; bool a1 = int.TryParse(a,out i);//转换成功,i=2
bool a2 = int.TryParse(b, out i);//转换失败,a2=false bool a3 = int.TryParse(c, out i);//转换失败,a3=false
通过Convert类进行转换:Convet类提供了多种类型的转换想
string a = "2"; int a1 = Convert.ToInt32(a);
可以通过继承即可IConventible或者TypeConventer类,实现自定义转换
使用as运算符转换:
//TODO
int.Parse()/Convert.ToInt()/int.TryParse()方法对比
参数和适用对象不同
- int.Parse():参数数据类型只能是string类型,适用于string类型的数据
- int.TryParse():参数也只能是string类型,适用于string类型的数据,但是在转换失败时会返回false,并且需要提供一个out类型的参数
- Convert.ToInt():参数类型较多
异常处理
- Convert.ToInt()参数为null,返回0,参数为""时,抛出异常
- int.Parse 参数为 null 时,抛出异常。参数为""时,抛出异常
- int.TryParse()方法比int.Parse()方法多了一个异常处理,如果出现异常则返回false,并且将输出参数返回0。
返回值
- int.TryParse与int.Parse和Convert.ToInt 在返回值的不同是返回bool类型。获取转换后的值是通过out参数获取的
比较相等
对象比较相等的机制有所不对,这取决于比较的是引用类型(类的实例)还是值类型(基本数据类型/结构/或枚举的实例)
默认情况下:
-
值类型使用值类型相等引用类型使用引用相等:两个值相等
- 引用类型使用引用相等:两个引用指向同一个对象
值类型比较相等(比较值相等),返回True
int x = 5, y = 5; Console.WriteLine(x == y);
引用类型比较相等(比较两个引用是否指向同一对象),返回True
string x = "5", y = x; Console.WriteLine(x == y);
==和!=运算符:编译器编译时根据操作数的数据类型决断使用何种方式比较,
- 对于基本类型比较的是基本类型的值
- 对于引用类型,比较的是对象的内存地址,不同的对象自然有不同的内存地址
int a = 5, b = 5; string x = "5", y = x; //a/b是值类型,所以会判断他们的值是否相等,返回True Console.WriteLine(a == b); //x/y是引用类型,所以判断他们是否指向统一对象,返回True Console.WriteLine(x == y);
Object.Equals虚方法:Equals在程序运行时决定比较的类型,根据对象的实际类型调用对应类中重写的Equals方法进行比较
int a = 5, b = 5; string x = "5", y = x; //调用System.Int32的Equals进行比较,返回True Console.WriteLine(a.Equals(b)); //调用System.String的Equals进行比较,返回True Console.WriteLine(x.Equals(y));
但是如果这里把string参数设置为null
string x = null, y = x; Console.WriteLine(x == y);//==依旧判断是否引用是否指向同一个对象,返回True Console.WriteLine(x.Equals(y));//第一个运算对象是null,Equals方法会抛出NullReferenceException异常;而静态的运算符则不会
Object静态的Equals方法:Object.Equals虚方法是在程序运行时决定比较的类型,根据对象的实际类型调用对应类中重写的Equals方法进行比较,如果对象类型是object怎么处理呢,答案Object类还提供了一个静态的Equals方法,可以对编译时不知道类型null对象进行安全的比较
object的静态ReferenceEquals方法
这里需要再学习补充