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 }
复制代码

 

 

 

  

 

 

  

 

 

 

posted @   Litrer  阅读(787)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示