共用方式為


類型測試運算子和轉換表示式 - isastypeof和 轉換

這些運算子和運算式會執行型別檢查或型別轉換。 is 運算子會檢查運算式的執行階段型別是否與給定型別相容。 as 運算子會將運算式明確地轉換成給定的型別 (如果其執行階段型別與該型別相容)。 轉換運算式會執行對目標型別的明確轉換。 typeof 運算子會取得某個型別的 System.Type 執行個體。

C# 語言參考資料記錄了 C# 語言最新版本。 同時也包含即將推出語言版本公開預覽功能的初步文件。

文件中標示了語言最近三個版本或目前公開預覽版中首次引入的任何功能。

小提示

欲查詢某功能何時首次在 C# 中引入,請參閱 C# 語言版本歷史的條目。

is 運算子

is 運算子會檢查運算式結果的執行階段型別是否與給定型別相容。 is 運算子也會對將運算式結果對模式進行測試。

使用型別測試 is 運算子運算式有下列格式

E is T

其中 E 是傳回值的表達式,而 T 是型別或型別參數的名稱。 E 不能是匿名方法或 Lambda 運算式。

當運算式結果為非 Null 且下列任何條件成立時,is 運算子會傳回 true

  • 運算式結果的執行時間類型會將身分識別轉換成 T

  • 運算式結果的執行階段型別衍生自型別 T、實作介面 T,或另一個隱含參考轉換從它到 T。 此條件涵蓋繼承關係與介面實作。

  • 運算式結果的執行階段型別是具有基礎型別 T,且Nullable<T>.HasValuetrue

  • 當表達式不是實例時,表達式結果的運行時類型和類型之間會存在 boxing 或 unboxing 轉換。

運算子 is 不會考慮使用者定義的轉換或隱含範圍轉換。

下列範例示範當運算式結果的執行階段型別衍生自給定型別 (表示型別之間存在參考轉換) 時,is 運算子傳回 true

public class Base { }

public class Derived : Base { }

public static class IsOperatorExample
{
    public static void Main()
    {
        object b = new Base();
        Console.WriteLine(b is Base);  // output: True
        Console.WriteLine(b is Derived);  // output: False

        object d = new Derived();
        Console.WriteLine(d is Base);  // output: True
        Console.WriteLine(d is Derived); // output: True
    }
}

下一個範例顯示 is 運算子考慮 Boxing 和 Unboxing 轉換,但不考慮數值轉換

int i = 27;
Console.WriteLine(i is System.IFormattable);  // output: True

object iBoxed = i;
Console.WriteLine(iBoxed is int);  // output: True
Console.WriteLine(iBoxed is long);  // output: False

如需 C# 轉換的資訊,請參閱 C# 語言規格轉換一章。

包含模式比對的型別測試

is 運算子也會對將運算式結果對模式進行測試。 下列範例示範如何使用宣告模式來檢查運算式的執行階段型別:

int i = 23;
object iBoxed = i;
int? jNullable = 7;
if (iBoxed is int a && jNullable is int b)
{
    Console.WriteLine(a + b);  // output 30
}

如需支援模式的相關資訊,請參閱模式

as 運算子

使用運算 as 子將表達式的結果明確轉換成給定的參考或可空值型別。 如果無法轉換,則 as 運算子會傳回 null。 不同於轉換運算式as 運算子一律不會擲回例外狀況。

以下格式的運算式

E as T

其中 E 是傳回值的表達式,而 T 是型別或型別參數的名稱,會產生與 相同的結果

E is T ? (T)(E) : (T)null

唯一不同的是 E 只會被評估一次。

as 運算子只考慮參考、可為 Null、Boxing 和 Unboxing 轉換。 您無法使用 as 運算子來執行使用者定義轉換。 要執行使用者自訂轉換,請使用 鑄造表達式

下列範例示範 as 運算子的用法:

IEnumerable<int> numbers = new List<int>(){10, 20, 30};
IList<int> indexable = numbers as IList<int>;
if (indexable != null)
{
    Console.WriteLine(indexable[0] + indexable[indexable.Count - 1]);  // output: 40
}

注意

如上述範例所示,您需要比較表達式的結果 asnull ,以檢查轉換是否成功。 您可以使用 is 運算符 來測試轉換是否成功,如果轉換成功,請將結果指派給新的變數。

轉換運算式

形式 (T)E 為 的 cast 表達式會明確將表達 E 式的結果轉換為型態 T。 若沒有從 的 E 類型 明確轉換到 型別 T,編譯器會發出錯誤。 在執行階段,明確轉換可能不會成功,且轉換運算式可能會擲回例外狀況。

下列範例示範明確的數值和參考轉換:

double x = 1234.7;
int a = (int)x;
Console.WriteLine(a);   // output: 1234

int[] ints = [10, 20, 30];
IEnumerable<int> numbers = ints;
IList<int> list = (IList<int>)numbers;
Console.WriteLine(list.Count);  // output: 3
Console.WriteLine(list[1]);  // output: 20

如需支援之明確轉換的資訊,請參閱 C# 語言規格明確轉換一節。 如需如何定義自訂明確或隱含型別轉換的資訊,請參閱使用者定義轉換運算子

() 的其他用法

您也使用括號來呼叫方法或叫用委派

另一個用括號的用途是調整 C# 在表達式中評估運算的順序。 如需詳細資訊,請參閱 C# 運算子

typeof 運算子

typeof運算子取得System.Type某個類型的實例。 typeof 運算子的引數必須是型別名稱或型別參數,如下列範例所示:

void PrintType<T>() => Console.WriteLine(typeof(T));

Console.WriteLine(typeof(List<string>));
PrintType<int>();
PrintType<System.Int32>();
PrintType<Dictionary<int, char>>();
// Output:
// System.Collections.Generic.List`1[System.String]
// System.Int32
// System.Int32
// System.Collections.Generic.Dictionary`2[System.Int32,System.Char]

這個參數不能是需要元資料註解的類型。 這些類型的例子包括以下幾種:

  • dynamic
  • string? (或任何可為 Null 的參考型別)

這些型別不會直接以中繼資料表示。 這些型別包含描述基礎型別的屬性。 在這兩種情況下,您可以使用基礎型別。 使用 dynamic 取代 object。 使用 string? 取代 string

您也能搭配使用 typeof 運算子和未繫結的泛型型別。 未繫結泛型型別的名稱必須包含適當數目的逗號,也就是比型別參數數目少一。 下列範例顯示搭配使用 typeof 運算子和未繫結泛型型別的用法:

Console.WriteLine(typeof(Dictionary<,>));
// Output:
// System.Collections.Generic.Dictionary`2[TKey,TValue]

運算式不能作為 typeof 運算子的引數。 若要取得運算式結果執行階段型別的 System.Type 執行個體,請使用 Object.GetType 方法。

使用 typeof 運算子的型別測試

使用 typeof 運算子來檢查運算式結果的執行階段型別,是否完全符合給定型別。 以下範例展示了使用 typeof 運算子與運算 is進行型別檢查的差異:

public class Animal { }

public class Giraffe : Animal { }

public static class TypeOfExample
{
    public static void Main()
    {
        object b = new Giraffe();
        Console.WriteLine(b is Animal);  // output: True
        Console.WriteLine(b.GetType() == typeof(Animal));  // output: False

        Console.WriteLine(b is Giraffe);  // output: True
        Console.WriteLine(b.GetType() == typeof(Giraffe));  // output: True
    }
}

運算子是否可多載

你不能讓 、 和 astypeof 運算子過載is

使用者自訂型別不會讓運算子超載, () 但它可以定義由 cast 表達式執行的自訂型別轉換。 如需詳細資訊,請參閱使用者定義轉換運算子

C# 語言規格

如需詳細資訊,請參閱 C# 語言規格的下列幾節:

另請參閱