2008-12-29 71 views
4

(int)reader[0]替換爲reader.GetInt32(0)有什麼優勢?我敢肯定,這樣的演員功能是有原因的,但除了感覺自己更喜歡避免演員的美感外,我不確定這些理由是什麼。Casting SqlDataReaders

+0

可以反映reader.Get(index)函數的源代碼嗎?我不認爲他們正在做一個演員,而是內部Convert.ToInt32。儘管可以稍微加快速度,但我在過去的演員中遇到了問題。 [也看到這個問題](http://stackoverflow.com/questions/221582/most-efficient-way-to-check-for-dbnull-and-then-assign-to-a-variable)。 DBNulls可能會導致問題,所以基本不投。 – nawfal 2013-02-05 18:26:43

+0

@nawal:不必要的,因爲MS共享[源代碼](http://referencesource.microsoft.com/netframework.aspx)。而這兩者之間的來源是非常不同的,但我目前沒有時間去探索原因。 – Brian 2013-02-05 20:32:50

回答

5

在代碼....

 void OneWay() 
     { 
      System.Data.SqlClient.SqlDataReader reader = null; 
      int i = reader.GetInt32(0); 
     } 

     void OtherWay() 
     { 
      System.Data.SqlClient.SqlDataReader reader = null; 
      int i = (int)reader[0]; 
     } 

在IL

.method private hidebysig instance void OneWay() cil managed 
{ 
    .maxstack 2 
    .locals init (
     [0] class [System.Data]System.Data.SqlClient.SqlDataReader reader, 
     [1] int32 i) 
    L_0000: nop 
    L_0001: ldnull 
    L_0002: stloc.0 
    L_0003: ldloc.0 
    L_0004: ldc.i4.0 
    L_0005: callvirt instance int32 [System.Data]System.Data.Common.DbDataReader::GetInt32(int32) 
    L_000a: stloc.1 
    L_000b: ret 
} 


.method private hidebysig instance void OtherWay() cil managed 
{ 
    .maxstack 2 
    .locals init (
     [0] class [System.Data]System.Data.SqlClient.SqlDataReader reader, 
     [1] int32 i) 
    L_0000: nop 
    L_0001: ldnull 
    L_0002: stloc.0 
    L_0003: ldloc.0 
    L_0004: ldc.i4.0 
    L_0005: callvirt instance object [System.Data]System.Data.Common.DbDataReader::get_Item(int32) 
    L_000a: unbox.any int32 
    L_000f: stloc.1 
    L_0010: ret 
} 

因此,IL是不同的,但我懷疑他們之間有任何明顯的差異。也許經過一百萬次迭代後,你會看到差異,但不太可能。

1

前者還可以接受列名作爲字符串而不是索引,並將嘗試將列值轉換爲int。後者只接受索引並且不會執行投射。

1

reader [0]返回一個System.Object,(int)reader [0]實際上是從Object到Int32進行強制轉換。

如果您調用GetXXX(0)方法,則不執行任何轉換。因此,從流中檢索的數據必須已經是指定方法的類型。

如果檢索到的數據類型不匹配,或者列有DBNull,則會引發InvalidCastException。