vb.net 和c#下的三目運算子的區別

來源:互聯網
上載者:User

     一直都以為這兩者之間的三目運算子是沒有區別的,只是vb是用iif,c#是?:而已。但是上次用了一次vb的iif之後卻發現兩者之間簡直是天淵之別。先看下面的代碼

Sub TestIIF()
        Dim d As DBNull = DBNull.Value
        Dim k As Integer = IIf(TypeOf d Is DBNull, 0, Convert.ToInt32(d))
        Console.WriteLine(k)
    End Sub

 

IL如下:

.method public static void  TestIIF() cil managed
{
  // 代碼大小       53 (0x35)
  .maxstack  3
  .locals init ([0] class [mscorlib]System.DBNull d,
           [1] int32 k)
  IL_0000:  nop
  IL_0001:  ldsfld     class [mscorlib]System.DBNull [mscorlib]System.DBNull::Value
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  isinst     [mscorlib]System.DBNull
  IL_000d:  ldnull
  IL_000e:  cgt.un
  IL_0010:  ldc.i4.0
  IL_0011:  box        [mscorlib]System.Int32
  IL_0016:  ldloc.0
  IL_0017:  call       int32 [mscorlib]System.Convert::ToInt32(object)
  IL_001c:  box        [mscorlib]System.Int32
  IL_0021:  call       object [Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::IIf(bool,
                                                                                            object,
                                                                                            object)
  IL_0026:  call       int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Conversions::ToInteger(object)
  IL_002b:  stloc.1
  IL_002c:  ldloc.1
  IL_002d:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_0032:  nop
  IL_0033:  nop
  IL_0034:  ret
} // end of method Module1::TestIIF

從il可以看出vb的iif是將前後兩個表達是計算出來然後裝相成object,然後再調用

object [Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::IIf(bool,object,object)。

所以如果你要執行以下語句

Dim k As Integer = IIf(TypeOf d Is DBNull, 0, Convert.ToInt32(d))

編譯器會直接報錯,因為要先將dbnull轉化為int裝箱。

 

再來看一下c#的三目運算子

代碼如下

static void TestThreeMU()
      {
            DBNull d = DBNull.Value;
            int k = d.GetType() == typeof(DBNull) ? 1 : Convert.ToInt32(DBNull.Value);
            Console.WriteLine(k);

      }

IL如下

.method private hidebysig static void  TestThreeMU() cil managed
{
  // 代碼大小       47 (0x2f)
  .maxstack  2
  .locals init ([0] class [mscorlib]System.DBNull d,
           [1] int32 k)
  IL_0000:  nop
  IL_0001:  ldsfld     class [mscorlib]System.DBNull [mscorlib]System.DBNull::Value
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  callvirt   instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
  IL_000d:  ldtoken    [mscorlib]System.DBNull
  IL_0012:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  IL_0017:  beq.s      IL_0025
  IL_0019:  ldsfld     class [mscorlib]System.DBNull [mscorlib]System.DBNull::Value
  IL_001e:  call       int32 [mscorlib]System.Convert::ToInt32(object)
  IL_0023:  br.s       IL_0026
  IL_0025:  ldc.i4.1
  IL_0026:  stloc.1
  IL_0027:  ldloc.1
  IL_0028:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_002d:  nop
  IL_002e:  ret
} // end of method Program::TestThreeMU

從IL中我們可以看見C#是直接將三目運算子編譯成一個bgt.s。所以

int k = d.GetType() == typeof(DBNull) ? 1 : Convert.ToInt32(DBNull.Value);

這一句代碼並不會出錯,因為IL跳到了IL_0025執行並不會執行轉碼。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.