我已经遇到过这种情况并且感到困惑。
Cat c = new Cat("Fluffy");
return (Animal)c;
Cat c = new Cat("Fluffy");
return c as Animal;
这两种语法存在的原因是什么?
答案 0 :(得分:14)
as
运算符是一个安全的演员。如果类型不兼容,as
将返回null
。
另一方面,如果类型不是赋值兼容的,那么显式强制转换(Animal)c
将抛出InvalidCastException
。
另外值得注意的是as
仅适用于继承关系,而显式转换运算符适用于值类型......
decimal d = 4.0m;
int i = (int)d;
...以及public static explicit operator
类型上定义的任何其他explicit conversion operators。这些不适用于as
。
答案 1 :(得分:5)
http://blogs.msdn.com/csharpfaq/archive/2004/03/12/88420.aspx
“使用as
运算符与C#中的强制转换不同,有三个重要方面:
1)当您尝试转换的变量不是请求的类型或其继承链时,它返回null,而不是抛出异常。
2)它只能应用于转换为引用类型的引用类型变量。
3)使用as不会执行用户定义的转换,例如隐式或显式转换运算符,这些转换运算符将执行转换。
实际上,在IL中定义了两个完全不同的操作来处理这两个关键字(castclass和isinst指令) - 它不仅仅是由C#编写的“语法糖”来获得这种不同的行为。与投射相比,微软CLR的v1.0和v1.1中的as运算符似乎稍微快一些(即使在没有无效投射的情况下,由于异常会严重降低投射的性能)。“答案 2 :(得分:2)
有了这个:
return (Animal)c;
你明确地说c是动物类型,如果没有出错的话。
有了这个:
return c as Animal;
你说你很确定c是动物类型,但也许不是所有的时间。
Eric Lippert在他的博客中谈到了这个问题:
答案 3 :(得分:0)
如果无法将对象强制转换为return (Animal)c;
类型,则强制转换语法Animal
将抛出InvalidCastException。如果你知道它是一个动物,这是很好的,如果不是,那么就会出现问题。
return c as Animal;
语法将返回null。如果您想避免捕获异常,这很方便:
Cat c = GetAnimal("Fluffy");
if (c == null)
{
AddAnimal("Fluffy");
}