型別測試運算子和 cast 運算式 (c # 參考)

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

is 運算子

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

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

E is T

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

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

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

  • 運算式結果的執行時間型別衍生自型別 T 、implements 介面 T 或另一個 隱含參考轉換 T

  • 運算式結果的執行時間類型為 可為 null 的實值型 別,其基礎類型為 T ,而 Nullable<T>.HasValuetrue

  • 從運算式結果的執行時間類型到類型的 裝箱取消 加入轉換都存在 T

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 運算子會考慮使用裝箱和取消載入的轉換,但不考慮 數值轉換

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 的實值型別。 如果無法轉換,則 as 運算子會傳回 null。 不同于 cast 運算式as 運算子永遠不會擲回例外狀況。

以下格式的運算式

E as T

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

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

但只會評估 E 一次。

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

下列範例示範 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 開始,您可以使用 operator 運算子 來測試轉換是否成功,如果成功,則將其結果指派給新的變數。

轉換運算式

格式為 (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]

您也可以使用運算子搭配未系結的 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# 語言規格的下列幾節:

另請參閱