C#中“As”关键字的重点是什么?

时间:2010-07-01 17:18:58

标签: c# keyword

来自文档:

  

as运算符就像一个转换器,除了它在转换失败时产生null而不是引发异常。更正式地说,表达形式:

   expression as type
     

相当于:

  expression is type ? (type)expression : (type) null
     

除了表达式只被评估一次。

那你为什么不选择以某种方式做到这一点。为什么有两个铸造系统?

7 个答案:

答案 0 :(得分:80)

它们不是两个铸造系统。两者有类似的行为,但意义却截然不同。 “as”表示“我认为这个对象可能实际上属于另一种类型;如果不是,则给我null。”演员表示两件事之一:

  • 我确信这个对象实际上是另一种类型。这样做,如果我错了,请崩溃程序。

  • 我确信这个对象不属于其他类型,但是有一种众所周知的方法可以将当前类型的值转换为所需类型。 (例如,将int转换为short。)实现它,如果转换实际上不起作用,则使程序崩溃。

有关详细信息,请参阅我关于此主题的文章。

http://blogs.msdn.com/b/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx

答案 1 :(得分:12)

效率和效果

执行演员表演的一部分是一些综合类型检查;因此,使用显式类型检查为实际强制转换添加前缀是多余的(类型检查会发生两次)。使用as关键字可确保只执行一次类型检查。您可能会想“但它必须执行空检查而不是第二次类型检查”,但与类型检查相比,空检查非常有效且高效。

if (x is SomeType )
{
  SomeType y = (SomeType )x;
  // Do something
}

进行2次检查,而

SomeType y = x as SomeType;
if (y != null)
{
  // Do something
}

生成1x - 与类型检查相比,空检查非常便宜。

答案 2 :(得分:11)

因为如果你不能像你期望的那样进行投射,有时候你会想要失败,有时候你不在乎,如果它不能投射,只想丢弃给定的对象。

它基本上是一个包含在try块中的常规强制转换的更快版本;但是As更具可读性,也可以节省打字。

答案 3 :(得分:7)

它允许快速检查而不需要尝试/转换开销,在某些情况下可能需要处理基于消息的继承树。

我经常使用它(收到消息,对特定的子类型做出反应)。尝试/施放wouuld要慢得多(每条消息都经过多次尝试/捕获帧) - 我们谈到在这里每秒处理200.000条消息。

答案 4 :(得分:2)

我通常根据代码的语义选择一个或另一个。

例如,如果您知道某个object必须是string,那么请使用(string),因为这表示编写代码的人确定该对象是一个string,如果它不是我们已经有比抛出的运行时强制转换异常更大的问题。

如果您不确定该对象是否属于特定类型但想要具有何时具有逻辑,请使用as。您可以使用is运算符,然后使用强制转换,但as运算符效率更高。

答案 5 :(得分:2)

让我给你一个真实世界的场景,你可以在哪里使用它们。

public class Foo
{
  private int m_Member;

  public override bool Equals(object obj)
  {
    // We use 'as' because we are not certain of the type.
    var that = obj as Foo;
    if (that != null)
    {
      return this.m_Member == that.m_Member;
    }
    return false;   
  }
}

和...

public class Program
{
  public static void Main()
  {
    var form = new Form();
    form.Load += Form_Load;
    Application.Run(form);
  }

  private static void Form_Load(object sender, EventArgs args)
  {
    // We use an explicit cast here because we are certain of the type
    // and we want an exception to be thrown if someone attempts to use
    // this method in context where sender is not a Form.
    var form = (Form)sender;

  }
}

答案 6 :(得分:0)

也许例子会有所帮助:

// Regular casting
Class1 x = new Class1();
Class2 y = (Class2)x; // Throws exception if x doesn't implement or derive from Class2

// Casting with as
Class2 y = x as Class2; // Sets y to null if it can't be casted.  Does not work with int to short, for example.

if (y != null)
{
  // We can use y
}

// Casting but checking before.
// Only works when boxing/unboxing or casting to base classes/interfaces
if (x is Class2)
{
  y = (Class2)x; // Won't fail since we already checked it
  // Use y
}

// Casting with try/catch
// Works with int to short, for example.  Same as "as"
try
{
  y = (Class2)x;
  // Use y
}
catch (InvalidCastException ex)
{
  // Failed cast
}