C#中的is, as 和 cast

C#做为静态强类型语言,要想使用好它,掌握好几种类型判断的方法是很基础也很必要的。如咱们所知,最经常使用的几种就是,isas铸型cast和自定义类型转换。可是这几种之间有什么区别是一个容易混淆的地方,如今让咱们来看看。安全

is

is以下场合返回true:测试

  • 实例属于该类型
class Person { }
   		Person p = new Person();
   		bool result = p is Person;
复制代码
  • 实例属于该类型的派生类型
class Manager : Person { }
   		Manager m = new Manager();
   		bool result = m is Person;
复制代码
  • 实例实现了该接口
interface IEmpty { }
                class ImplememntEmpty : IEmpty { }
                ImplememntEmpty instance = new ImplememntEmpty();
                var result = instance is IEmpty;
复制代码
  • 实例拆箱以后类型能够匹配
var obj = 10l;
   		var result = obj is long;
复制代码

注意,is关键字不会考虑用户自定的类型转换,不管是implicit仍是explicit都不会考虑。  spa

as

as关键字和is牢牢关联,在内部,as关键字是这么处理的,code

instace is type ? (type)instance : (type)null 
复制代码

因此在使用as的时候,有两个地方须要注意。接口

  • 要想经过as完成转型,首先要确保实例能经过is测试,也就是说,用户自定义的类型转换仍是不会被考虑。
  • as转型失败的时候会返回一个null,因此as的目标必须是能引用类型或者是可空值类型,不然编译器会报错。考虑下面这个例子,
object obj = 10l;
                        var result = obj as long; //这里会报错
复制代码

正确的写法是ci

object obj = 10l;
                        var result = obj as long?; //这里就没问题了,这样确保了在转型失败的状况下,null能够赋值给long?
复制代码

 

cast

cast分为显式转型和隐式转型,当编译器检测出转型不会形成数据精度损失,或者不会有转型风险的时候,不须要使用显式转型,反之,若是显式转型是必须的。编译器

  • 对于值类型来讲,从低精度到高精度的转型被视做无精度损失,是安全的,好比从int到long, 从float到double。反之则须要显式转型,旨在告诉编译器用户知晓这种转型可能会影响精度,用户甘愿接受这种精度损失。
float f = 10;
            double d = f;
            int i = 10;
            long l = i;

			//下面开始是显式转型
            i = (int)l;
            f = (float)d;
复制代码
  • 对于引用类型来讲,从子类像父类的转换老是安全的,成功的,这里不须要显式转型。可是反过来,显式转型是须要的,由于从父类转换到子类不老是会成功。
class Person { }
			class Manager : Person { }

			Manager m = new Manager();
                        Person p = m;
			
			//如下须要显式转型,请注意,在这里若是p不是一个Manager,显式转型会抛异常。因此在使用显式转型的地方,建议使用as或者加入try catch以增长代码安全
			m = (Manager)p;
复制代码

 

用户自定义类型转换

上面的Cast可使用到用户自定义类型转换,和Cast有显式和隐式同样,用户自定义类型转换也有显式隐式之分。分别用关键字explicitimplicit区分,在调用的时候,显式转换可使用用户自定义的显式和隐式转换,而隐式转换就要求用户必须提供自定义的隐式转换。 用户自定义类型转换的做用在于给本来可能风马牛不相及的类型之间提供了一个转换通道,让它们相互转换成为了可能,而这一切,在自定义类型转换出来以前,极可能是编译器禁止的。it

class Company { }
			class Corporation { }
			Company c = new Company();
                        Corporation cor = (Corporation)c; //编译器会报错,声称没法将Company类型转换成Corporation
复制代码

添加显式自定义类型转换io

class Company 
			{ 
				public static explicit operator Corporation(Company c) {
                            	    return new Corporation();
                        	}
  			}
复制代码

这样编译器就能知道咱们提供了一个自定义转换从Company到Corporation,这样上面那段代码就能够工做了。 隐式用户自定义转换相似,只是把关键字explicit换成implicit便可。编译

相关文章
相关标签/搜索