C# 关键字 类型测试运算符(is、as、typeof、强制转换表达式)
一、类型测试运算符有is、as、typeof。
1、is运算符:用于检测表达式的运行时类型是否与给定的类型兼容。
2、as运算符:用于将表达式显示转换为给定的类型(如果其运行时类型与该类型兼容)。
3、typeof运算符:用于获取某个类型的System.Type实力。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Csharp关键字 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 14 Program p = new Program(); 15 p.IsMark(); 16 p.AsMark(); 17 p.Exchange(); 18 p.TypeofMark(); 19 p.CompareIsAndTypeof(); 20 } 21 22 public void IsMark() 23 { 24 //E is T 25 /* 26 * 其中E是一个返回值表达式,T是类型或类型参数的名称。E不得为匿名方法或者lambda表达式 27 * 如果E的结果为非null且可以通过引用转换(继承或者接口实现)、装箱转换(将类型转换为Object)或取消装箱(将Object类型转换为其子类)转换为类型T,则E is T表达式返回true, 28 * 否则返回false,is运算符不会考虑用户自定义的转换。 29 */ 30 #region 引用转换(继承或者接口实现) 31 Object b = new Base(); 32 Console.WriteLine(b is Base);//检查一个类转换为该类本身时,返回true; 33 Console.WriteLine(b is Derived);//检查一个类转换为该类的子类时返回false; 34 35 Object d = new Derived(); 36 Console.WriteLine(d is Base);//检查一个类转换为该类的父类时,返回true; 37 Console.WriteLine(d is Derived);//检查一个类转换为该类本身时,返回true; 38 Console.ReadKey(); 39 #endregion 40 41 #region 装箱和拆箱转换(不考虑数值转换) 42 int i = 27; 43 Console.WriteLine(i is System.IFormattable);//true。这里不太清楚是什么操作。 44 object iBoxed = i; 45 Console.WriteLine(iBoxed is int);//将Object类型转换为int属于取消装箱操作。返回true; 46 Console.WriteLine(iBoxed is long);//因为iBoxed是一个int类型的数字转换为Object,无法拆箱为long,返回false。 47 Console.ReadKey(); 48 #endregion 49 #region 有模式匹配的类型测试 50 /* 51 * 从 C# 7.0 开始,is 运算符还会对照某个模式测试表达式结果。 具体而言,它支持以下形式的类型模式: 52 * E is T v 53 * 其中,E 为返回值的表达式,T 为类型或类型参数的名称,v 为类型 T 的新局部变量。 54 * 如果 E 的结果为非 null 且可以通过引用、装箱或取消装箱转换来转换为 T, 55 * 则 E is T v 表达式将返回 true,E 结果转换后的值将分配给变量 v。 56 */ 57 58 int? jNullable = 7; 59 if (iBoxed is int a && jNullable is int c) 60 { 61 Console.WriteLine(a + c); // output 34 62 } 63 Console.ReadKey(); 64 #endregion 65 } 66 public void AsMark() 67 { 68 /* 69 * as运算符将表达式结果显式转换为给定的引用或可以为null值的类型。 70 * 如果无法进行转换,则as运算符返回null。 71 * 与强制转换表达式不同,as运算符永远不会引发异常。 72 * 形式如下的表达式 73 * E as T 74 * 其中,E 为返回值的表达式,T 为类型或类型参数的名称,生成相同的结果, 75 * E is T ? (T)(E) : (T)null 76 * 不同的是 E 只计算一次。 77 * as 运算符仅考虑引用、可以为 null、装箱和取消装箱转换。 78 * 不能使用 as 运算符执行用户定义的转换。 79 * 为此,请使用强制转换表达式。 80 */ 81 IEnumerable<int> numbers = new[] { 10, 20, 30 }; 82 IList<int> indexable = numbers as IList<int>; 83 if (indexable != null) 84 { 85 Console.WriteLine(indexable[0] + indexable[indexable.Count - 1]); // output: 40 86 } 87 Console.ReadKey(); 88 } 89 public void Exchange() 90 { 91 /* 92 * 形式为 (T)E 的强制转换表达式将表达式 E 的结果显式转换为类型 T。 93 * 如果不存在从类型 E 到类型 T 的显式转换,则发生编译时错误。 94 * 在运行时,显式转换可能不会成功,强制转换表达式可能会引发异常。 95 * 下面的示例演示显式数值和引用转换: 96 */ 97 double x = 1234.7; 98 int a = (int)x; 99 Console.WriteLine(a); // output: 1234 100 101 IEnumerable<int> numbers = new int[] { 10, 20, 30 }; 102 IList<int> list = (IList<int>)numbers; 103 Console.WriteLine(list.Count); // output: 3 104 Console.WriteLine(list[1]); // output: 20 105 } 106 public void TypeofMark() 107 { 108 /* 109 * typeof 运算符用于获取某个类型的 System.Type 实例。 110 * typeof 运算符的实参必须是类型或类型形参的名称,如以下示例所示: 111 */ 112 void PrintType<T>() => Console.WriteLine(typeof(T)); 113 114 Console.WriteLine(typeof(List<string>)); 115 PrintType<int>(); 116 PrintType<System.Int32>(); 117 PrintType<Dictionary<int, char>>(); 118 // Output: 119 // System.Collections.Generic.List`1[System.String] 120 // System.Int32 121 // System.Int32 122 // System.Collections.Generic.Dictionary`2[System.Int32,System.Char] 123 //=================================================================== 124 /* 125 * 你还可以使用具有未绑定泛型类型的 typeof 运算符。 126 * 未绑定泛型类型的名称必须包含适当数量的逗号,且此数量小于类型参数的数量。 127 * 以下示例演示了具有未绑定泛型类型的 typeof 运算符的用法: 128 */ 129 Console.WriteLine(typeof(Dictionary<,>)); 130 // Output: 131 // System.Collections.Generic.Dictionary`2[TKey,TValue] 132 // 表达式不能为 typeof 运算符的参数。 133 //若要获取表达式结果的运行时类型的 System.Type 实例,请使用 Object.GetType 方法。 134 // 135 } 136 public void CompareIsAndTypeof() 137 { 138 /* 139 * 使用 typeof 运算符来检查表达式结果的运行时类型是否与给定的类型完全匹配。 140 * 以下示例演示了使用 typeof 运算符和 is 运算符执行的类型检查之间的差异: 141 */ 142 object b = new Giraffe(); 143 Console.WriteLine(b is Animal); // output: True 144 Console.WriteLine(b.GetType() == typeof(Animal)); // output: False 145 146 Console.WriteLine(b is Giraffe); // output: True 147 Console.WriteLine(b.GetType() == typeof(Giraffe)); // output: True 148 } 149 } 150 151 public class Base { } 152 public class Derived : Base { } 153 public class Animal { } 154 public class Giraffe : Animal { } 155 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了