轉型和型別轉換,是將運算式從一種資料型態改成另一種的兩種不同方式。
運算式可以透過轉型運算子(<type>)轉型成另一種型別。
long l = 1000L;
int i = (int)l;
object o = new Random();
Random r = (Random)o;
如果型別不相容,就會擲回InvalidCastException的執行個體。以數字來說,這表示接收的型別無法表示轉型後的值。以類別來說,其中一個型別必須衍生自另一個(這對結構來說也同樣成立,只是顯而易見)。
轉型_的另一種做法,是使用is運算子的_型別轉換。這種做法通常用在參考型別和可為 Null 的型別上。
object o = new Random();
if (o is Random rand)
{
int ii = rand.Next();
// now, do something random
}
如果你需要偵測物件的確切型別,is可能就稍微寬鬆了點,因為對某個類別,以及它直接或間接衍生的任何類別和介面,它都會傳回 true。在這種情況下,typeof和Object.GetType()就是解答。
object o = new List<int>();
o is ICollection<int> // true
o.GetType() == typeof(ICollection<int>) // false
o is List<int> // true
o.GetType() == typeof(List<int>) // true
我們的足球俱樂部 football-match-reports 在各大聯賽中氣勢如虹,這次你又受邀來幫忙,負責安全通行證的印製系統。
後勤人員的類別階層如下
TeamSupport (interface)
├ Chairman
├ Manager
└ Staff (abstract)
├ Physio
├ OffensiveCoach
├ GoalKeepingCoach
└ Security
├ SecurityJunior
├ SecurityIntern
└ PoliceLiaison
這個階層的完整實作已包含在練習的原始程式碼中。
所有傳入安全通行證產生器的資料都已經過驗證,並保證不為 null。
請實作 SecurityPassMaker.GetDisplayName() 方法。對於所有衍生自 Staff 的類別執行個體,它應該回傳 Title 欄位的值;否則應回傳 "Too Important for a Security Pass"。
var spm = new SecurityPassMaker();
spm.GetDisplayName(new Manager());
// => "Too Important for a Security Pass"
spm.GetDisplayName(new Physio());
// => "The Physio"
請修改 SecurityPassMaker.GetDisplayName() 方法。它的行為應該與任務 1 相同,差別在於:如果該員工是安全團隊的成員(型別為 Security 或其衍生類別),則應在職稱之後顯示 " Priority Personnel"。
var spm = new SecurityPassMaker();
spm.GetDisplayName(new Physio());
// => "The Physio"
var spm2 = new SecurityPassMaker();
spm2.GetDisplayName(new Security());
// => "Security Team Member Priority Personnel"
spm2.GetDisplayName(new SecurityJunior());
// => "Security Junior Priority Personnel"
請修改 SecurityPassMaker.GetDisplayName() 方法。它的行為應該與任務 2 相同,差別在於:對於型別為 SecurityJunior、SecurityIntern 和 PoliceLiaison 的執行個體,不應顯示 " Priority Personnel"。
var spm2 = new SecurityPassMaker();
spm2.GetDisplayName(new Security());
// => "Security Team Member Priority Personnel"
spm2.GetDisplayName(new SecurityJunior());
// => "Security Junior"