前言
类型转换从根本上说是类型铸造,或者说是把数据从一种类型转换为另一种类型。在 C# 中,类型铸造有两种形式:
- Implicit 隐式类型转换 - 这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失。例如,从小的整数类型转换为大的整数类型,从派生类转换为基类。
- Explicit 显式类型转换 - 显式类型转换,即强制类型转换。显式转换需要强制转换运算符,而且强制转换会造成数据丢失。
隐式转换与显示转换的选择
- 从低精度到高精度的类型可以进行隐式转换而不会报错,反过来会报错误"无法将类型xxx隐式转换为xxx",将只能进行显式转换。
- 从派生类对象到基类对象可以进行隐式转换,隐式转换为基类后,本质上还是派生类对象,引用的还是同一个对象的内存。从基类对象到派生类对象只能进行显示转换,且不一定成功,如果基类对象引用的对象不是派生类对象,则显示转换会失败,编译期不会报错,而运行期会报错误“无法将类型xxx的对象强制转换为类型xxx”。
private class Student
{ }
private class Graduate : Student { }
public static void Main(string[] args)
{
Graduate g = new Graduate();
Student s = g;
Graduate g2 = (Graduate)s; // 没问题
Student s2 = new Student();
Graduate g3 = (Graduate)s2; // 错误
}
- 如果两个数组纬度相同,而且彼此数组元素之间可以进行引用转换(隐式的或者显式的),那么两个数组之间就可以进行引用转换,且转换的方式和元素之间相同。
Graduate[] g = { new Graduate(), new Graduate()};
Student[] s = g; // 隐式转换
Graduate[] g2 = (Graduate[])s; // 显示转换
- object 对象与值类型的转换。由于在C#中,所有类和类型都是从object类派生而来,所以所有类型的实例都可以隐式转换为 object 对象(装箱Boxing),也可以从obejct对象显式转换回来(拆箱Unboxing)。
- 由于object对象是引用类型,而int, uint ,char, float等是值类型,使用object对象到值类型的双向转换可以将值类型和引用类型联系在一起。
int x = 3;
object a = x; // 装箱
int y = (int)a; // 拆箱
- 从类的实例可以隐式转换为接口的实例。