黑马程序员技术交流社区

标题: 关于对象转换的is与as问题 [打印本页]

作者: 高腾    时间: 2013-6-14 00:21
标题: 关于对象转换的is与as问题
本帖最后由 高腾 于 2013-6-15 14:12 编辑

声明一个父类Father,一个继承自Father的子类Son和Daughter类
Son s = new Son();
Father f1 = s;//创建一个Father类的对象指向Son类
f1 = new Daughter();;//强制将f1指向Daughter类
有两种方法可以判断f1为何种类型
1)if(f1 is Son) {输出为Son类型}
      else {输出为Daughter类型}
2)Son s1 = f1 as Son;(如果转换失败,s1则为null)
对于第二种as转换失败了不会报错,而是返回一个null值,可以接着根据s1是否为null判断转换是否成功,达到了既转换又能判断的目的
而is只能判断f1指向了哪种类型,这个可以看出as比is有过之而无不足,那is存在的优势是什么呢?
作者: 许庭洲    时间: 2013-6-14 06:26
对象的隐士转换和显示转换:
Chinese ch =new Chinese();
//隐士转换,把子类变量赋值给父类变量
Person p = ch;
//显示转换,把父类变量赋值给子类变量
Person p = new Chinese();
Chinses ch = (Chinese)p;
//如果对象不在同一个继承路径上
//则不能强制类型转换
Dog g = new Dog();
Chinese ch = (Chinese)g;//错误
//is 运算
if(p is Chinese)
{
       Console.WriteLine("中国人"):
}
else if(p is Korean)
{
       Console.WriteLine("韩国人"):
}
作者: 高腾    时间: 2013-6-14 07:07
许庭洲 发表于 2013-6-14 06:26
对象的隐士转换和显示转换:
Chinese ch =new Chinese();
//隐士转换,把子类变量赋值给父类变量

你这个只提到了强制类型转换和is判断
我想问的是is和as的优缺点,is能做的,as都能做
为什么还会存在is?
作者: 无__畏    时间: 2013-6-14 07:32
is的表达式返回的是bool类型,单纯的判断。

as是类型转换,如果类型相同就返回一个引用,否则就返回null。
作者: 高腾    时间: 2013-6-14 07:34
无__畏 发表于 2013-6-14 07:32
is的表达式返回的是bool类型,单纯的判断。

as是类型转换,如果类型相同就返回一个引用,否则就返回null。 ...

但是使用as也可以做判断
判断对象是否为空 为空就说明转换成功
能起到is的作用
那is的优势在哪里
作者: 无__畏    时间: 2013-6-14 07:38
as存在类型转换!  你判断他的时候 他多了一步类型转换么
比如  美国人 as 地球人   
原来这个人是美国人  你一as  我们就只知道他是个地球人了  就不知道他是美国的

作者: 无__畏    时间: 2013-6-14 07:40
美国人 is 地球人   
判断他是个地球人  那就返回true就完了  他还是原来的美国人
作者: 高腾    时间: 2013-6-14 07:42
无__畏 发表于 2013-6-14 07:38
as存在类型转换!  你判断他的时候 他多了一步类型转换么
比如  美国人 as 地球人   
原来这个人是美国人  ...

啊 我昏了 我先想的是能转换就最好不过了
所以一直觉得as比is好
没有想过只判断不转换的情形
谢谢 懂了
作者: 无__畏    时间: 2013-6-14 07:47
就如:  我说:哥们 老师在办公室么   你告诉我在或者不再就OK拉  这是is
           我说: 哥们  帮我找一下老师,然后你把老师叫出来了   这是as

       不能,我说哥们老师在办公室么,你把老师给我叫出来了  证明他刚在办公室
作者: 江湖一浪人    时间: 2013-6-14 08:29
对于is的使用,我就据下面我写的例子讲解吧:
            string path = @"E:\";
            DirectoryInfo dir = new DirectoryInfo(path);
            //获取特定目录下的子目录集合
            DirectoryInfo[] directories = dir.GetDirectories();
            //获取特定目录下的文件集合
            FileInfo[] files = dir.GetFiles();
            foreach (DirectoryInfo di in directories)
            {
                Console.WriteLine(di);
            }
            //一起取得目录集合和文件集合
            System.IO.FileSystemInfo[] fsi = dir.GetFileSystemInfos();
            for (int i = 0; i < fsi.Length; i++)
            {
                //用多态区分类型
                System.IO.FileSystemInfo si = fsi;
                //is as 的使用
                if (si is DirectoryInfo)
                {
                    Console.Write("{0} ", "目录");
                }
                else
                {
                    Console.Write("{0}  ", "文件");
                }
                Console.WriteLine(fsi.Name);
System.IO.FileSystemInfo[]使用这个类时,它里面有目录文件和文本文件,那么就可以使用多态进行判断并输出:si is DirectoryInfo判断是否为目录文件
is关键字用于检查对象是否与给定类型兼容,如果被检查对象能够强制转换成给定类型并不发生异常,那么表示它们类型兼容。如果所提供的表达式非空,并且所提供的对象可以强制转换为所提供的类型而不会导致引发异常,则is表达式的计算结果将是 true;否则,发生异常时is表达式将返回false,就这么简单的区别。希望对你有用。
作者: 彭康    时间: 2013-6-14 08:42
if(o is Employee) {
   Employee e = (Employee) o;// is 的用法
   //在if语句中使用e
}

Employee e = o as Employee; //as 的用法
if(e != null)
{
   //在if语句中使用e
}

反编译的话 其实 is 被 as 封装了,目的是为了让用户使用更舒适就如同第一种结构。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2