隐式转换 显示转换---强制转换(“不管是否发生数据丢失,都进行转换吧”)
1、数字转换
占据较少位数的数字类型可以隐式转换为占据较多位数的数字类型:
2 溢出检测上下文
checked unchecked 可以做运算符使用
ushort sh = 2000;
byte b;
b = unchecked((byte)sh);//大多数重要的高位丢失了变成了208
b = checked((byte)sh);//抛出OverflowException的异常
,也可以做语句使用。
unchecked
{
b = (byte)sh;
Console.WriteLine(b);
checked
{
b = (byte)sh;
Console.WriteLine(b);
}
}
3 引用转换
classA { publicint Field1; }
classB : A { publicint Field2;}
classProgram2
{
staticvoid Main()
{
B b = newB();
Console.WriteLine("{0}", b.Field1);
Console.WriteLine("{0}", b.Field2);
A a = (A)b;
Console.WriteLine("{0}", a.Field1);
Console.WriteLine("{0}", a.Field2);//编译错误对象a实际指向B类型的对象,即和对象b实际是指向内存中的相同对象,但对象a是属于类型A的对象,因此看不到B扩展部分
}
}
4 引用类型的显示和隐式转换
隐式引用转换:所有引用类型都可以被隐式转换为object类型;任何类型都可以隐式转换到它继承的接口;类可以隐式转换到它继承的父类;类可以隐式转换到它实现的接口。
显示引用转换是从一个普通类型转换到一个更精确类型的转换,包括从object类到任何引用类型的转换;从基类到继承它的子类的转换。
5 装箱转换
装箱:是一种值类型到引用类型的隐式转换,它接受值类型的值,根据这个值在堆上创建一个完整的引用类型对象并返回对象引用。
例如: int i=12; object oi=null; oi=i; 这就是一次装箱 在堆上创建i的引用对象
int i = 10; object oi = i; i = 12; oi = 15; 这里装箱后会产生两个副本:原始值类型和引用类型,各自可以独立操作。对i装箱并将引用赋值给oi
6 拆箱转换
拆箱:是将装箱后的引用类型显示转换为值类型的过程。
int j = (int)oi;
7 自定义转换
自定义转换:用户为类或结构定义隐式或显示转换。
classPerson
{
publicstring Name;
publicint Age;
public Person(string name, int age)
{
Name = name;
Age = age;
}
publicstaticimplicit operatorint(Person p) //将Person转换为int
{
return p.Age;
}
publicstaticimplicitoperatorPerson(int i)
{
returnnewPerson("YXX", i);
}
}
classProgram
{
staticvoid Main()
{
Person bill = newPerson("bill",25);
int age = bill;//将Person对象转换为int变量
Console.WriteLine("Person Info:{0},{1}", bill.Name, age);
Person anon = 35;//将int转换为Person对象
Console.WriteLine("Person Info:{0},{1}", anon.Name, anon.Age);
}
}
其中,public和static修饰符是必需的。如果使用explicit,则定义的是显示转换,在使用时必须使用强制转换,
int age = (int)bill;
以上int age = bill;,还可以 float fAge=bill; 因为从int到float是系统定义的标准隐式转换。
8 is运算符
只能用与引用转换,装箱和拆箱转换,不能用于自定义转换。用来检查转换是否会成功完成。
if(bill is Person) //检测变量bill是否能成功转换为Person类型
9 as 运算符
p = bill as Person;
if(p != null)
as运算符只能用于引用转换和装箱转换。as运算符和强制转换运算符类似,只是as不抛出异常,如果转换失败,就返回null。因此在使用前做判断,以检查是否转换成功。