C#编译器会优化我的代码可读性度量吗?

时间:2013-06-19 11:17:25

标签: c# compilation

有时我会得到高度重复的代码块,尤其是在处理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是否作为一个无用的参考后编辑?

1 个答案:

答案 0 :(得分: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