1

有时我会得到高度重复的代码块,尤其是在处理 DAL 代码时。

例如:

command.Parameters.Add("@CName", SqlDbType.NVarChar, 50).Value = c.Name.DisplayName;
command.Parameters.Add("@LKey", SqlDbType.NVarChar, 15).Value = c.Alf;
command.Parameters.Add("@SalesTerritoryId", SqlDbType.NVarChar, 15).Value = c.Profile.SalesTerritoryId;
command.Parameters.Add("@CAQ", SqlDbType.TinyInt).Value = (short)c.Profile.Quadrant;

回到 VB 中,有 With 语句可以很好地整理东西。偶尔在 C# 中我会做类似的事情:

var cp = command.Parameters;
cp.Add("@CName", SqlDbType.NVarChar, 50).Value = c.Name.DisplayName;
cp.Add("@LKey", SqlDbType.NVarChar, 15).Value = c.Alf;
cp.Add("@SalesTerritoryId", SqlDbType.NVarChar, 15).Value = c.Profile.SalesTerritoryId;
cp.Add("@CAQ", SqlDbType.TinyInt).Value = (short)c.Profile.Quadrant;

就我个人而言,我发现这更具可读性,但我想知道是否在编译时,两个版本是否都成为相同的 IL,因为编译器足够聪明,可以知道我做了什么并简单地优化它?

还是 cp 作为无用的参考后编译保留?

4

1 回答 1

1

即使是编译形式,它也会保持不变。(我没有尝试任何优化开关,只是简单的旧版本构建)。问题是 ngen 将对 MSIL 做什么,但就 MSIL 而言,它确实很重要。

static void foo() {
  var command = new SqlCommand();
  command.Parameters.Add("@Name", SqlDbType.NVarChar, 50).Value = "";
}

static void bar() {
  var command = new SqlCommand();
  var cp = command.Parameters;
  cp.Add("@Name", SqlDbType.NVarChar, 50).Value = "";
}

福:

    .method private hidebysig static void  foo() cil managed
{
  // Code size       37 (0x25)
  .maxstack  4
  .locals init ([0] class [System.Data]System.Data.SqlClient.SqlCommand command)
  IL_0000:  newobj     instance void [System.Data]System.Data.SqlClient.SqlCommand::.ctor()
  IL_0005:  stloc.0
  IL_0006:  ldloc.0
  IL_0007:  callvirt   instance class [System.Data]System.Data.SqlClient.SqlParameterCollection [System.Data]System.Data.SqlClient.SqlCommand::get_Parameters()
  IL_000c:  ldstr      "@Name"
  IL_0011:  ldc.i4.s   12
  IL_0013:  ldc.i4.s   50
  IL_0015:  callvirt   instance class [System.Data]System.Data.SqlClient.SqlParameter [System.Data]System.Data.SqlClient.SqlParameterCollection::Add(string,
                                                                                                                                                     valuetype [System.Data]System.Data.SqlDbType,
                                                                                                                                                     int32)
  IL_001a:  ldstr      ""
  IL_001f:  callvirt   instance void [System.Data]System.Data.Common.DbParameter::set_Value(object)
  IL_0024:  ret
} // end of method Program::foo

酒吧:

.method private hidebysig static void  bar() cil managed
{
  // Code size       39 (0x27)
  .maxstack  4
  .locals init ([0] class [System.Data]System.Data.SqlClient.SqlCommand command,
           [1] class [System.Data]System.Data.SqlClient.SqlParameterCollection cp)
  IL_0000:  newobj     instance void [System.Data]System.Data.SqlClient.SqlCommand::.ctor()
  IL_0005:  stloc.0
  IL_0006:  ldloc.0
  IL_0007:  callvirt   instance class [System.Data]System.Data.SqlClient.SqlParameterCollection [System.Data]System.Data.SqlClient.SqlCommand::get_Parameters()
  IL_000c:  stloc.1
  IL_000d:  ldloc.1
  IL_000e:  ldstr      "@Name"
  IL_0013:  ldc.i4.s   12
  IL_0015:  ldc.i4.s   50
  IL_0017:  callvirt   instance class [System.Data]System.Data.SqlClient.SqlParameter [System.Data]System.Data.SqlClient.SqlParameterCollection::Add(string,
                                                                                                                                                     valuetype [System.Data]System.Data.SqlDbType,
                                                                                                                                                     int32)
  IL_001c:  ldstr      ""
  IL_0021:  callvirt   instance void [System.Data]System.Data.Common.DbParameter::set_Value(object)
  IL_0026:  ret
} // end of method Program::bar
于 2013-06-19T11:29:10.750 回答