2012-10-10 153 views
0

我试图更改与im循环的数据表的列名相匹配的属性值(使用反射)。更改属性值会导致所有属性的更改

这里是我变化的代码属性:

Type type = myTypeBuilder.CreateType(); 
foreach (DataRow row in table.Rows) 
{ 
object testobject = Activator.CreateInstance(retval, true); 
foreach (DataColumn col in table.Columns) 
{ 
    PropertyInfo property = testobject .GetType().GetProperty(col.ColumnName); 
    property.SetValue(testobject , row[col], BindingFlags.CreateInstance, null, null, null); 
} 
} 

至于结果,即时得到,而IM在表中DataColumns循环,但的SetValue毕竟我的属性值“右键属性testobject“设置为只有选定属性应具有的值。

这是我生成类型的方式:

foreach (DataColumn col in table.Columns) 
     { 
      string propertyname=col.ColumnName; 
      // The last argument of DefineProperty is null, because the 
      // property has no parameters. (If you don't specify null, you must 
      // specify an array of Type objects. For a parameterless property, 
      // use an array with no elements: new Type[] {}) 

      PropertyBuilder custNamePropBldr = myTypeBuilder.DefineProperty(propertyname, System.Reflection.PropertyAttributes.None, typeof(string), null); 
      // The property set and property get methods require a special 
      // set of attributes. 
      MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; 

      // Define the "get" accessor method for CustomerName. 
      MethodBuilder custNameGetPropMthdBldr = myTypeBuilder.DefineMethod("get_"+propertyname, getSetAttr, typeof(string), Type.EmptyTypes); 

      ILGenerator custNameGetIL = custNameGetPropMthdBldr.GetILGenerator(); 
      custNameGetIL.Emit(OpCodes.Ldarg_0); 
      custNameGetIL.Emit(OpCodes.Ldfld, customerNameBldr); 
      custNameGetIL.Emit(OpCodes.Ret); 

      // Define the "set" accessor method for CustomerName. 
      MethodBuilder custNameSetPropMthdBldr = myTypeBuilder.DefineMethod("set_"+propertyname, getSetAttr, null, new Type[] { typeof(string) }); 

      ILGenerator custNameSetIL = custNameSetPropMthdBldr.GetILGenerator(); 
      custNameSetIL.Emit(OpCodes.Ldarg_0); 
      custNameSetIL.Emit(OpCodes.Ldarg_1); 
      custNameSetIL.Emit(OpCodes.Stfld, customerNameBldr); 
      custNameSetIL.Emit(OpCodes.Ret); 

      // Last, we must map the two methods created above to our PropertyBuilder to 
      // their corresponding behaviors, "get" and "set" respectively. 
      custNamePropBldr.SetGetMethod(custNameGetPropMthdBldr); 
      custNamePropBldr.SetSetMethod(custNameSetPropMthdBldr); 
     } 

你知道可能是什么原因?

谢谢

何塞。

+0

您能否详细说明*,但在SetValue之后,我的“testobject”的所有属性值都设置为只有选定属性应具有的值。 –

回答

1

似乎你的customerNameBldr在foreach循环中永远不会改变(当你生成类型时)。

这样,所有属性设置者和获取者都引用相同的字段,因此所有设置者将更改同一字段的值,并且所有属性获取者都将获得同一字段的值。

custNameGetIL.Emit(OpCodes.Ldfld, customerNameBldr);