【问题标题】:Which code is better: using "as" or "is"? [duplicate]哪个代码更好:使用“as”还是“is”? [复制]
【发布时间】:2012-08-25 14:38:01
【问题描述】:

可能重复:
Casting vs using the 'as' keyword in the CLR
C#: “is” vs “as”

这段代码:

    if (sheet.Models.Data is GroupDataModel)
    {
        GroupDataModel gdm = (GroupDataModel)sheet.Models.Data;

还有这段代码:

    GroupDataModel gdm = sheet.Models.Data as GroupDataModel;
    if (gdm != null)
    {

你推荐以上两种风格中的任何一种吗?

【问题讨论】:

  • 第一个。如果无法进行强制转换,第二个可能会抛出异常
  • 定义“更好”——为了什么?表现?可读性?错误?还有什么?
  • 第一个的优点是不会在程序中引入可能为空的符号
  • @AndreCalil - 类型询问将防止 InvalidCastException。但是,NullReferenceException is 在第一个选项中仍然可能,但不是第二个。
  • @KeithS:两者都可以抛出NullReferenceException,因为sheetsheet.Models 可能为空。

标签: c# syntax casting operators


【解决方案1】:

FxCop 提倡后者,因为演员只需要执行一次(as

【讨论】:

    【解决方案2】:

    我认为它更好,因为它可以转换以及您可以轻松地进行检查..第二个很好

    更多信息:Explicit and Implicit Casting of object and Role of 'is' and 'as' keyword in Explicit casting

    as 和 is 的区别

    • 作为运算符将一种类型转换为另一种类型,如果转换则返回 Null 失败。如果它是可转换的,则无需再次转换。

    • is 运算符检查天气一个对象是否可以转换为另一种类型,如果不是则返回 false。因此,如果它可转换,则需要将对象转换为基本类型。

    【讨论】:

    • 进行演员阵容所需的努力是微乎其微的。这当然是一个微优化。您应该使用更具可读性的代码,或者在逻辑上对您更有意义的代码。性能在这里不应该是一个问题。
    【解决方案3】:

    有趣的是,这两个版本在这种情况下产生了相同的 IL:

    代码

    void Main() {
        Class1 inst1 = new Class1();
        ((inst1 as Class1) != null).Dump();
    
        Class1 inst2 = new Class1();
        (inst2 is Class1).Dump();
    }
    
    class Class1 { }
    

    IL

    IL_0001:  newobj      UserQuery+Class1..ctor
    IL_0006:  stloc.0     
    IL_0007:  ldloc.0     
    IL_0008:  ldnull      
    IL_0009:  ceq         
    IL_000B:  ldc.i4.0    
    IL_000C:  ceq         
    IL_000E:  call        LINQPad.Extensions.Dump
    IL_0013:  pop         
    IL_0014:  newobj      UserQuery+Class1..ctor
    IL_0019:  stloc.1     
    IL_001A:  ldloc.1     
    IL_001B:  ldnull      
    IL_001C:  ceq         
    IL_001E:  ldc.i4.0    
    IL_001F:  ceq         
    IL_0021:  call        LINQPad.Extensions.Dump
    
    Class1..ctor:
    IL_0000:  ldarg.0     
    IL_0001:  call        System.Object..ctor
    IL_0006:  ret   
    

    【讨论】:

    【解决方案4】:

    首选第二个版本。

    第二个版本只需要一次型式测试。如果测试成功,第一个需要两次类型测试(首先是 is,然后是演员表)。

    【讨论】:

    • 如果无法进行强制转换,会不会抛出异常?
    • @AndreCalil:两个版本都没有抛出异常。
    • 第一个可以,具体取决于上下文。在多线程情况下,sheet.Models.Data 可能会在类型检查时转换为 GroupDataModel,但不是在强制转换时。
    • @SeanU:+1 这是一个很好的观点。描述这种情况的技术术语是“竞争条件”。
    【解决方案5】:

    如果您以后要使用类型化对象,请使用“as”。

    如果您不打算将对象与类型本身一起使用,请使用“is”。

    如果您期望这些对象属于该特定类型,则是另一个问题。然后只需使用强制转换,如果类型不是您所期望的,让它抛出异常。

    【讨论】:

      猜你喜欢
      • 2015-03-04
      • 1970-01-01
      • 2015-11-03
      • 1970-01-01
      • 2018-05-09
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多