裝箱boxing:
是值類型到引用類型的隱式轉換,根據值類型的值,在堆上創建一個完整的引用類型對象,並返回對象的引用。
int i = 1; //值類型
object o = i; //引用類型,在堆上創建int對象,將i的值賦值給對象,將對象的引用返回給o
裝箱操作後,原值類型與新引用類型相互獨立,可以單獨操作。
int i = 1;
object o = i;
Debug.Log(i + " - " + o); // 1 - 1
i = 2;
o = 3;
Debug.Log(i + " - " + o); // 2 - 3
拆箱unboxing:
是引用類型到值類型的顯式轉換,是把裝箱之後的對象轉換回值類型。
對象必須拆箱轉換爲原始類型,否則會報錯。
int i = 1;
object o = i;
int j = (int)o;
Debug.Log(j); // 1
string s = (string)o; //報錯(InvalidCastException: Specified cast is not valid.)
溢出檢測:
顯示轉換可能會導致溢出或丟失數據,
關鍵字checked會檢測溢出,並在溢出時拋出異常,
int intValue = 123456;
byte byteValue;
checked
{
byteValue = (byte)intValue;
Debug.Log(byteValue); // 報錯(OverflowException: Arithmetic operation resulted in an overflow.)
}
關鍵字unchecked會忽略溢出,(不使用該關鍵字也是忽略溢出)
int intValue = 123456;
byte byteValue;
byteValue = (byte)intValue;
Debug.Log(byteValue); // 64
unchecked
{
byteValue = (byte)intValue;
Debug.Log(byteValue); // 64
}
自定義隱式/顯式轉換:
除了標準轉換,還可以使用關鍵字implicit和explicit,爲類和結構自定義隱式和顯式轉換:
public static implicit/explicit operator TargetType(SourceType identifer)
自定義要求:
1. 需要public和static關鍵字;
2. 只有類和結構可以自定義轉換;
3. 不能重定義標準轉換;
4.1 源類型與目標類型不能相同;
4.2 源類型與目標類型不能有繼承關聯;
4.3 源類型與目標類型不能是接口或object類型;
4.4 轉換運算符必須是源類型或目標類型的成員;
public class Person
{
public Person(string _name, int _age)
{
name = _name;
age = _age;
}
public string name;
public int age;
//隱式轉換
public static implicit operator string(Person person)
{
if (person == null)
return string.Empty;
return person.name;
}
public static implicit operator Person(string name)
{
return new Person(name, 0);
}
//顯示轉換
public static explicit operator int(Person person)
{
if (person == null)
return 0;
return person.age;
}
public static explicit operator Person(int age)
{
return new Person(string.Empty, age);
}
}
public void TestFunc()
{
string name = "xiaoming";
//隱式轉換
Person person = name;
Debug.Log(person);
//顯示轉換
int age = (int)person;
Debug.Log(age);
}
附
運算符is/as:
對於引用轉換和拆箱裝箱轉換,可以在轉換前使用is運算符,檢查轉換是否能成功,從而避免程序報錯;
as運算符與強制轉換運算符類似,只是在轉換失敗是不會報錯,會返回null。
public class Animal { public string name; }
public class Dog : Animal { }
private void Start()
{
Dog dog = new Dog() { name = "abc" };
if (dog is Animal)
{
Animal animal = dog as Animal;
Debug.Log(animal.name);
}
}