as 运算符

  as运算符使用下面的语法,把一种类型转换为指定的引用类型:

  1. <operand> as <type>

  这只适用于下列情况:

  1. <operand> 的类型是 <type> 类型
  2. <operand> 可以隐式转换为 <type> 类型
  3. <operand> 可以封箱到 <type> 类型中

  如果不能从<operand>转换为<type>,则表达式的结果就是null

  基类到派生类的转换可以使用显式转换来进行,但这并不总是有效的。考虑前面示例中的两个类ClassA和ClassD,其中ClassD派生于ClassA:

  1. class ClassA : IMyInterface
  2. {
  3. }
  4. class ClassD : ClassA
  5. {
  6. }

  下面的代码使用 as 运算符把 obj1 中存储的 ClassA 实例转换为 ClassD 类型:

  1. ClassA obj1 = new ClassA();
  2. ClassD obj2 = obj1 as ClassD;

  则obj2的结果为 null

  还可以使用多态性把 ClassD 实例存储在 ClassA 类型的变量中。下面的代码演示了这一点,ClassA 类型的变量包含 ClassD 类型的实例,使用 as 运算符把 ClassA 类型的变量转换为 ClassD 类型。

  1. ClassD obj1 = new ClassD();
  2. ClassA obj2 = obj1;
  3. ClassD obj3 = obj2 as ClassD;

  这次obj3最后包含与obj1相同的对象引用,而不是null

  因此,as运算符非常有用,因为下面使用简单类型转换的代码会抛出一个异常:

  1. ClassA obj1 = new ClassA();
  2. ClassD obj2 = (ClassD)obj1;

  与此代码等价的as代码会把null值赋予obj2,不会抛出异常。这表示,下面的代码(使用本章前面开发的两个类:Animal和派生于Animal的一个类Cow)在C#应用程序中是很常见的:

  1. public void MilkCow(Animal myAnimal)
  2. {
  3. Cow myCow = myAnimal as Cow;
  4. if(myCow != null)
  5. {
  6. myCow.Milk();
  7. }
  8. else
  9. {
  10. Console.WriteLine("{0} isn't a cow, and so can't be milked.",
  11. myAnimal.Name);
  12. }
  13. }

  这要比检查异常简单得多!