類型測試運算子和轉換運算式 (C# 參考)

您可以使用下列運算子和運算式來執行類型檢查或類型轉換:

is 運算子

is運算子會檢查運算式結果的執行時間類型是否與指定型別相容。 從 C# 7.0 開始, is 運算子也會根據模式測試運算式結果。

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

E is T

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

is運算子會在 true 運算式結果為非 Null 且下列任何條件為 true 時傳回:

  • 運算式結果的執行時間類型為 T

  • 運算式結果的執行時間類型衍生自 類型 T 、實作介面 T ,或從它轉換成 T 的另一個隱含參考轉換

  • 運算式結果的執行時間類型是具有基礎型別且 為 true可為 Null 實值型TNullable<T>.HasValue 別。

  • 從運算式結果的執行時間類型轉換為 類型 T ,存在Boxingunboxing轉換。

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# 語言規格轉換一章。

包含模式比對的型別測試

從 C# 7.0 開始, 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 運算子將運算式的結果明確地轉換成給定參考或可為 Null 的實值型別。 如果無法轉換,運算子會 asnull 回 。 不同于 轉換運算式as 運算子永遠不會擲回例外狀況。

以下格式的運算式

E as T

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

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

但只會評估 E 一次。

as 運算子只考慮參考、可為 Null、Boxing 和 Unboxing 轉換。 您無法使用 as 運算子來執行使用者定義的轉換。 若要這樣做,請使用 轉換運算式

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

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

注意

如上述範例所示,您需要將 as 陳述式的結果與 null 比較,以檢查轉換是否成功。 從 C# 7.0 開始,您可以使用 is 運算子 來測試轉換是否成功,如果成功,請將結果指派給新的變數。

轉換運算式

格式為 (T)E 的轉換運算式會執行明確轉換,將運算式 E 的結果轉換成型別 T。 如果沒有從型別 E 轉換成型別 T 的明確轉換存在,就會發生編譯時期錯誤。 在執行階段,明確轉換可能不會成功,且轉換運算式可能會擲回例外狀況。

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

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

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

如需支援之明確轉換的資訊,請參閱 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
    }
}

運算子是否可多載

isastypeof 運算子無法多載。

使用者定義型別無法多載 () 運算子,但可以定義可由轉換運算式執行的自訂類型轉換。 如需詳細資訊,請參閱使用者定義轉換運算子

C# 語言規格

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

另請參閱