该文为总结,具体参考以下:
- 参考文档:
https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/type-testing-and-conversion-operators#is-operator - 文档: is运算计算步骤:
https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/language-specification/expressions#the-is-operator - 博客:
https://www.cnblogs.com/rush/archive/2011/05/13/as_is.html
一. is运算符
- E is T
- E 是返回一个值的表达式,T 是类型或类型参数的名称。 E 不得为匿名方法或 Lambda 表达式。
- 如果E不为空并且可以通过引用转换、装箱转换或拆箱转换将E转换为类型 T,则 E is T 表达式将返回 true;否则,它将返回 false。
- is 运算符不会考虑用户定义的转换。
- 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
- E is T v
- 从 C# 7.0 开始支持
- E 结果转换后的值将分配给变量 v。
二. as运算符
E as T
- as 运算符将表达式E显式转换的结果为:给定的引用或可以为 null 值的类型(T)。
- 如果无法进行转换,则 as 运算符返回 null
- 不能使用 as 运算符执行用户定义的转换
- as 运算符永远不会引发异常
三. 各种运算符、转换之间的区别
1. as和强制转换之间的区别
- as只支持引用类型(考虑引用转换),强制转换都支持
- as转换失败会返回null,强制转换失败会引发异常
2. is和as的区别
- E as T的结果等于:
E is T ? (T)(E) : (T)null
- 不同的是 E 只计算一次。所以说E as T效率更高
3. typeof和Object.GetType 的区别
- typeof 运算符:检查表达式结果的运行时类型是否与给定的类型完全匹配
- 以下代码演示:
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
}
}
- 可以看到一个是调用object的方法,一个是传递类型
三. 补充
- 用户自定义的转换操作符只作用于对象的编译时类型而非运行时类型,也就是在编译时就完成了转换。详细见前面的博客。