MiCoos 哟,写bug呢?

C#基础 类型转换

2019-09-04
GHMicoos

概述:我们常常需要把对象从一种类型转换为另一种类型。

零 类型转换

0.隐式转换

  • 只要能保证值不会发生变化,类型转换就可以自动(隐式)进行。
  • 有种特殊情况,long/ulong转换为float,这种转换可能会损失数据,但是编译器认为这是一种可以接受的错误。编译器认为只是精度变低了,其值大小不会受影响。
  • 派生类转换为基类,是隐式转换。因为派生类必然属于基类。

1.显示转换

  • 语法:把强制转换的目标类型名放在要转换的值之前的()中。或者使用as运算符。
  • 使用as运算符有好处就是,无法转换时候,不会抛出异常;单该运算符只能用于引用类型。
  • 基类转换为派生类,是显示转换。基类不一定是派生类的类型。

2.装箱与拆箱–类型转换实例

  • C# 值类型存储在栈上,引用类型存储在堆上。
  • 装箱(boxing):把值类型转换为引用类型。
  • 拆箱(unboxing):把引用类型转换为值类型。
  • 装箱是隐式转换,拆箱是显示转换。分析,值类型是派生自System.ValueType,System.ValueType派生自System.Object;所以从基本类型到object(boxing)是从派生类型到基本类型的转换,是隐式的;从object到基本类型(unboxing)是从基类到派生类的转换,所以是显示的。

  • 装箱、拆箱之所以重要,装箱太频繁会造成明显性能损失。

int i = 10;
//装箱 是隐式转换,性能影响大
object iObj = i;
//拆箱 是显示转换
var ii = (int)iObj;

一 自定义强制类型转换

0.定义强制类型转换

  • 强制类型转换的语法类似于重载运算符。
  • 隐式转换implicit,显示转换explicit

class Person
{
    public int Age { get; set; }
    public float Height { get; set; }

    public static implicit operator float(Person p)
        => p.Height;
    public static explicit operator Person(float hegiht)
        =>new Person { Height=hegiht};
}

//测试代码
var p = new Person() { Age=10,Height=1.4f};
//隐式转换
var height = p;
//显示转换
var newP = (Person)height;

1.自定义的限制

  • 定义不同结构或者类的实例之间的类型强制类型转换(隐式、显示)是完全合法的。但是有限制
    • 如果某个类派生自另一个类,就不能定义这连个类之间的类型强制转换(因为这些类型的强制类型转换已经存在了)
    • 类型强制转换必须在源数据类型或者目标数据类型的内部定义。
  • System.Object -> A -> B -> C
  • System.Object -> A -> B -> D
  • 备注:上面这个继承层次中,值有CD才能自定义类型转换。

2.多重强制类型转换

  • 如果在进行要求的数据类型转的时候,C#编译器没有可用的直接强制转换方式,C#编译器就会寻找一种转换方式,把几种强制转换合并起来。

var p = new Person() { Age=10,Height=1.4f};
//隐式转换 类似于 p->float->double
double height = p;


Similar Posts

下一篇 C#基础 事件

Comments