'as`和`is`的真正用途

14 c# language-features keyword

我没有 - as或者is在C#或任何支持该关键字的语言中使用过.

你用它做什么用的?

我不是说我如何使用它我的意思是你真的需要它?

我还在一个相当大的c ++项目中没有进行类型转换(我很自豪).

所以考虑到我几乎从不打字,为什么我需要关键字asis

mar*_*c_s 34

我必须编写代码来枚举放置在ASP.NET webform上的所有控件,并对特定控件执行某些操作,例如为所有Textbox添加背景颜色,等等.

的主要好处asis对我来说,我可以放心地检查变量是否是使用给定类型的is无异常情况发生.一旦我确定它属于给定类型,我就可以安全轻松地将其转换为所需类型as.

我基本上做了什么(简化!)是一个

foreach(Control c in form.Controls)
{
   if(c is Textbox)
      HandleTextbox(c as Textbox);

   if(c is Listbox)
      HandleListbox(c as Listbox);
}
Run Code Online (Sandbox Code Playgroud)

等等.没有as,is这将是一个很麻烦,恕我直言.

基本上,你可能需要或可以好好利用的asis,如果你与多态性处理很多-如果你有事情可以在我的示例页面上任意数量的类型,如控制列表.如果您没有或不使用多态,那么您不太可能遇到对这些运算符的需求.

  • 最好的形式(以及你应该使用的形式而不是上面的形式)是`Textbox tb = c as Textbox; if(tb!= null)HandleTextbox(tb);` (10认同)
  • 你不妨在这里施展.您已经使用is来测试对象的正确类型.http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx (4认同)
  • 我收回了更多的工作.我只是运行一个测试,至少对于字符串,"as"运算符(IsInst操作码)似乎比cast(CastClass操作码)更快......但是"As"和null检查是最快的(假设你想要实例而不是只是类型检查.应该指出"as"只适用于类. (4认同)
  • @Matthew:是的,你可以 - 你认为这更容易/更具可读性吗?我不这么认为...... (2认同)
  • 每当我看到这种形式的东西时,我内心的某些东西就会尖叫"使用多态!!!!" (2认同)

Dav*_*uge 15

我在事件处理程序中使用'as'作为一个方便的快捷方式,以便在设计时无法知道发送方时将发送对象恢复.

protected void SomeButtonInAGridView_Click(object sender, EventArgs e)
{
    Button clickedButton = sender as Button;
}
Run Code Online (Sandbox Code Playgroud)

  • +1.非常适合重复使用事件处理程序,这是一个非常好的做法. (2认同)
  • 是的,我知道它永远是一个按钮,但是为了能够访问单击的按钮属性,我觉得语法比Button clickedButton =(Button)sender更干净,更容易阅读; (2认同)

Mat*_*ley 10

这是一个很多出现的:

class Foo {
     public override bool Equals(object obj)
     {
         // The more specific function needs to do null checking anyway.
         return Equals(obj as Foo);
     }

     public bool Equals(Foo obj)
     {
         // do some comparison here.
     }
}
Run Code Online (Sandbox Code Playgroud)

  • 并不是的.如果你使用`is`,那么你需要转换为`Foo`才能进行比较(除非所有的Foo都相等!). (2认同)
  • 也就是说,微软建议使用重载:`Equals(Foo)`和`覆盖Equals(object)`.这消除了铸造的负担并且完全提供了更清晰的代码 (2认同)

Abe*_*bel 8

有趣的问题.实际上,我一直都在使用它们.is可以很方便地找出一个对象是否属于某种类型,我偶尔会在泛型中使用它,或者在不同类型的对象中循环使用它.它对反射也很有价值.

另一个,as发现了更多的用途.使用正常转换通常更安全:当它失败时,它返回null,而不是异常.我也发现它更清晰,更容易使用它,检查null的返回值,然后添加一个异常块.

基本上,我的意思是说,我更喜欢这个:

protected void GeneralEventHandler(object sender, EventArgs e)
{
    Button btn = sender as Button;
    if(btn != null)   // click came from a button!
        // do something
    else
        // other cases
}
Run Code Online (Sandbox Code Playgroud)

还有这个:

protected void GeneralEventHandler(object sender, EventArgs e)
{
    if(sender is Button)   // click came from a button!
        // do something
    else
        // other cases
}
Run Code Online (Sandbox Code Playgroud)

与此相反:

protected void GeneralEventHandler(object sender, EventArgs e)
{
    try 
    {
        Button btn = (Button) sender;
        // if we get this far, it's a button
    }
    catch(InvalidCastException ice)
    {
        // click did not come from a button! Handle other cases
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这只是一个例子,但是当我可以避免尝试/捕获时,我会.这也为真正的例外提供了更多的空间.


Chr*_*yer 7

我用它来干净地从DataReader可能的数据中获取数据DBNull.

int? personHeight = dr["Height"] as int?;
Run Code Online (Sandbox Code Playgroud)

要么

int personHeight = dr["Height"] as int? ?? 0;
Run Code Online (Sandbox Code Playgroud)