类型测试和强制转换运算符(C# 引用)Type-testing and cast operators (C# reference)

可以使用以下运算符来执行类型检查或类型转换:You can use the following operators to perform type checking or type conversion:

is 运算符is operator

is 运算符检查表达式结果的运行时类型是否与给定类型兼容。The is operator checks if the runtime type of an expression result is compatible with a given type. 从 C# 7.0 开始,is 运算符还会对照某个模式测试表达式结果。Beginning with C# 7.0, the is operator also tests an expression result against a pattern.

具有类型测试 is 运算符的表达式具有以下形式The expression with the type-testing is operator has the following form

E is T

其中 E 是返回一个值的表达式,T 是类型或类型参数的名称。where E is an expression that returns a value and T is the name of a type or a type parameter. E 不得为匿名方法或 Lambda 表达式。E cannot be an anonymous method or a lambda expression.

如果 E is T 的结果为非 null 且可以通过引用转换、装箱转换或取消装箱转换来转换为类型 true,则 E 表达式将返回 T;否则,它将返回 falseThe E is T expression returns true if the result of E is non-null and can be converted to type T by a reference conversion, a boxing conversion, or an unboxing conversion; otherwise, it returns false. is 运算符不会考虑用户定义的转换。The is operator doesn't consider user-defined conversions.

以下示例演示,如果表达式结果的运行时类型派生自给定类型,即类型之间存在引用转换,is 运算符将返回 trueThe following example demonstrates that the is operator returns true if the runtime type of an expression result derives from a given type, that is, there exists a reference conversion between types:

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 运算符将考虑装箱和取消装箱转换,但不会考虑数值转换The next example shows that the is operator takes into account boxing and unboxing conversions but doesn't consider numeric conversions:

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# 语言规范转换一章。For information about C# conversions, see the Conversions chapter of the C# language specification.

有模式匹配的类型测试Type testing with pattern matching

从 C# 7.0 开始,is 运算符还会对照某个模式测试表达式结果。Beginning with C# 7.0, the is operator also tests an expression result against a pattern. 具体而言,它支持以下形式的类型模式:In particular, it supports the type pattern in the following form:

E is T v

其中,E 为返回值的表达式,T 为类型或类型参数的名称,v 为类型 T 的新局部变量。where E is an expression that returns a value, T is the name of a type or a type parameter, and v is a new local variable of type T. 如果 E 的结果为非 null 且可以通过引用、装箱或取消装箱转换来转换为 T,则 E is T v 表达式将返回 trueE 结果转换后的值将分配给变量 vIf the result of E is non-null and can be converted to T by a reference, boxing, or unboxing conversion, the E is T v expression returns true and the converted value of the result of E is assigned to variable v.

以下示例演示了具有以下类型模式的 is 运算符的用法:The following example demonstrates the usage of the is operator with the type pattern:

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

有关类型模式和其他受支持模式的详细信息,请参阅具有 is 的模式匹配For more information about the type pattern and other supported patterns, see Pattern matching with is.

as 运算符as operator

as 运算符将表达式结果显式转换为给定的引用或可以为 null 值的类型。The as operator explicitly converts the result of an expression to a given reference or nullable value type. 如果无法进行转换,则 as 运算符返回 nullIf the conversion is not possible, the as operator returns null. 强制转换运算符 () 不同,as 运算符永远不会引发异常。Unlike the cast operator (), the as operator never throws an exception.

形式如下的表达式The expression of the form

E as T

其中,E 为返回值的表达式,T 为类型或类型参数的名称,生成相同的结果,where E is an expression that returns a value and T is the name of a type or a type parameter, produces the same result as

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

不同的是 E 只计算一次。except that E is only evaluated once.

as 运算符仅考虑引用、可以为 null、装箱和取消装箱转换。The as operator considers only reference, nullable, boxing, and unboxing conversions. 不能使用 as 运算符执行用户定义的转换。You cannot use the as operator to perform a user-defined conversion. 若要执行此操作,请使用强制转换运算符 ()To do that, use the cast operator ().

下面的示例演示 as 运算符的用法:The following example demonstrates the usage of the as operator:

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 进行比较,以检查转换是否成功。As the preceding example shows, you need to compare the result of the as expression with null to check if the conversion is successful. 从 C# 7.0 开始,你可以使用 is 运算符测试转换是否成功,如果成功,则将其结果分配给新变量。Beginning with C# 7.0, you can use the is operator both to test if the conversion succeeds and, if it succeeds, assign its result to a new variable.

强制转换运算符 ()Cast operator ()

形式为 (T)E 的强制转换表达式将表达式 E 的结果显式转换为类型 TA cast expression of the form (T)E performs an explicit conversion of the result of expression E to type T. 如果不存在从类型 E 到类型 T 的显式转换,则发生编译时错误。If no explicit conversion exists from the type of E to type T, a compile-time error occurs. 在运行时,显式转换可能不会成功,强制转换表达式可能会引发异常。At run time, an explicit conversion might not succeed and a cast expression might throw an exception.

下面的示例演示显式数值和引用转换:The following example demonstrates explicit numeric and reference conversions:

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# 语言规范显式转换部分。For information about supported explicit conversions, see the Explicit conversions section of the C# language specification. 有关如何定义自定义显式或隐式类型转换的信息,请参阅用户定义转换运算符For information about how to define a custom explicit or implicit type conversion, see User-defined conversion operators.

() 的其他用法Other usages of ()

你还可以使用括号调用方法或调用委托You also use parentheses to call a method or invoke a delegate.

括号的其他用法是调整表达式中计算操作的顺序。Other use of parentheses is to adjust the order in which to evaluate operations in an expression. 有关详细信息,请参阅 C# 运算符For more information, see C# operators.

TypeOf 运算符typeof operator

typeof 运算符用于获取某个类型的 System.Type 实例。The typeof operator obtains the System.Type instance for a type. typeof 运算符的实参必须是类型或类型形参的名称,如以下示例所示:The argument to the typeof operator must be the name of a type or a type parameter, as the following example shows:

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 运算符。You also can use the typeof operator with unbound generic types. 未绑定泛型类型的名称必须包含适当数量的逗号,且此数量小于类型参数的数量。The name of an unbound generic type must contain the appropriate number of commas, which is one less than the number of type parameters. 以下示例演示了具有未绑定泛型类型的 typeof 运算符的用法:The following example shows the usage of the typeof operator with an unbound generic type:

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

表达式不能为 typeof 运算符的参数。An expression cannot be an argument of the typeof operator. 若要获取表达式结果的运行时类型的 System.Type 实例,请使用 Object.GetType 方法。To get the System.Type instance for the runtime type of an expression result, use the Object.GetType method.

使用 typeof 运算符进行类型测试Type testing with the typeof operator

使用 typeof 运算符来检查表达式结果的运行时类型是否与给定的类型完全匹配。Use the typeof operator to check if the runtime type of the expression result exactly matches a given type. 以下示例演示了使用 typeof 运算符和 is 运算符执行的类型检查之间的差异:The following example demonstrates the difference between type checking performed with the typeof operator and the is operator:

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
    }
}

运算符可重载性Operator overloadability

isastypeof 运算符无法进行重载。The is, as, and typeof operators cannot be overloaded.

用户定义的类型不能重载 () 运算符,但可以定义可由强制转换表达式执行的自定义类型转换。A user-defined type cannot overload the () operator, but can define custom type conversions that can be performed by a cast expression. 有关详细信息,请参阅用户定义转换运算符For more information, see User-defined conversion operators.

C# 语言规范C# language specification

有关更多信息,请参阅 C# 语言规范的以下部分:For more information, see the following sections of the C# language specification:

另请参阅See also