概述
在了解运行运算符的前提我们需要了解什么是RTTI ,在任何一门面向对象的语言中,都有RTTI这个概念(即 运行时)。
RTTI(Run-Time Type Identification),通过运行时类型信息程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。
RTTI提供了以下两个非常有用的操作符:
(1)typeid(C#中叫TypeOf)操作符,返回指针和引用所指的实际类型。
面向对象的编程语言,像C++,Java,delphi,C#都提供了对RTTI的支持。 本文将简略介绍 RTTI 的一些背景知识、描述 RTTI 的概念,并通过具体例子和代码介绍什么时候使用以及如何使用 RTTI;本文还将详细描述两个重要的 RTTI 运算符的使用方法, 下面我们来开始学习吧。
注:本文没有介绍赋值运算符、比较运算符、逻辑运算符、三目运行符等一二三元运算,这个在前面java 基础文章有提到,请参考本人Java基础或其他人的博客,没有基础运算符的理解,这个文章很难能看懂?
运行时类型标识
-
运行时标识有什么用呢?
1.运行时类型标识,能预先测试某个强制类型转换操作,能否成功,从而避免无效的强制类型转换异常。
2. 在c#中有三个支持RTTI的关键字:is 、 as 、typeof。 下面依次介绍他们。
- IS运算符
通过is运算符,能够判断对象类型是否为特顶类型,如果两种类型是相同类型,或者两者之间存在引用,装箱拆箱转换,则表明两种类型是兼容的。
class Program { static void Main(string[] args) { People p1 = new People(); Person p2 = new Person(); if (p1 is People) { Console.WriteLine("p1 是 People 的对象 ~~~"); } if (p2 is People) { //这个打印,因为p2是Person类型的对象,而Person类型派生于People类型 //由于Person对象可以转换为People类型,因此Person对象与People类型是兼容的,但是反过来就不成立 Console.WriteLine("p2 是 People 的对象..."); } if (p1 is Person) { Console.WriteLine("p1 是 Person 的对象***"); } if (p2 is Person) { Console.WriteLine("p2 是 Person 的对象---"); } if (p1 is object) { Console.WriteLine("任何类的父类为object"); } Console.Read(); } } /// <summary> /// 个人信息 /// </summary> public class People { public string Name { get; set; } public int Age { get; set; } public string Sex { get; set; } } /// <summary> /// 人的群体信息 /// </summary> public class Person: People { public string Household { get; set; } }
as运算符:
在运行期间执行类型转换,并且能够使得类型转换失败不抛异常,而返回一个null值。
using System; using System.Collections.Generic; using System.Data; namespace testData { class Program { static void Main(string[] args) { People p1 = new People() { Age=30,Sex="女",Name="mainaizi" }; Person p2 = new Person() { Age=29,Sex="男",Name="大棒槌",Household="北京昌平" }; Person p = p1 as Person; //as类型先检查强制类型转换的有效性,如果有效,则执行强类型转换过程。这些都在这一句完成。 Console.WriteLine(p); Console.WriteLine("清输入任意字符按Enter继续..."); string s= Console.ReadLine(); try { Person person = (Person)p1; } catch (Exception exe) { Console.WriteLine(exe.Message); } People people = p2; Console.WriteLine(people);//这里执行的是自动转换 所以不需要强制类型转换,我们大类型转换小类型的转换叫做自动转换 Console.Read(); } } public class PersonAnws { /// <summary> /// 自定义隐士转换 /// </summary> /// <param name="v">被转化类型</param> public static implicit operator PersonAnws(People v) { People p = new People(); return p; } /// <summary> /// 自定义显示转换【这里不过多解释】 /// </summary> /// <param name="v"></param> public static explicit operator Int32(PersonAnws p) { return 0; } } /// <summary> /// 个人信息 /// </summary> public class People { public string Name { get; set; } public int Age { get; set; } public string Sex { get; set; } public override string ToString() { return "{"+$"name:{this.Name},age:{this.Age},sex{this.Sex}"+"}"; } } /// <summary> /// 人的群体信息 /// </summary> public class Person: People { public string Household { get; set; } public override string ToString() { return "{" + $"name:{base.Name},age:{base.Age},sex{base.Sex},Household:{this.Household}" + "}"; } } }
typeof运算符:
as ,is 能够测试两种类型的兼容性。但大多数情况下,还需要获得某个类型的具体信息。这就用到了typeof,它可以返回与具体类型相关的System.Type对象,通过System.Type对象可以去顶此类型的特征。一旦获得给定类型的Type对象,就可以通过使用该对象定义的各种属性,字段,方法来获取类型的具体信息。Type类包含了很多成员,我们一起来看下吧。
using System; using System.Collections.Generic; using System.Data; namespace testData { class Program { static void Main(string[] args) { Type type= typeof(Person); Console.WriteLine(type); Console.WriteLine(type.FullName);//完整名称 Console.WriteLine(type.Name);//类名称 Console.WriteLine(type.BaseType);//基类 Console.WriteLine(type.IsSealed);//是否为密封类 Console.WriteLine(type.IsPublic);//是否是共有的 Console.Read(); } } /// <summary> /// 个人信息 /// </summary> public class People { public string Name { get; set; } public int Age { get; set; } public string Sex { get; set; } public override string ToString() { return "{"+$"name:{this.Name},age:{this.Age},sex{this.Sex}"+"}"; } } /// <summary> /// 人的群体信息 /// </summary> public class Person: People { public string Household { get; set; } public override string ToString() { return "{" + $"name:{base.Name},age:{base.Age},sex{base.Sex},Household:{this.Household}" + "}"; } } }
说到typeOf我们不得不说下类型的装载
列如
Type er= Type.GetType("System.String");
Console.WriteLine(er.Name);
我们管这种的获取类的类型叫做配件的装载。配件装载只能在本程序集中进行搜索,也就是说,在本程序集的命名空间下进行搜索。