【发布时间】:2015-02-19 18:38:37
【问题描述】:
我在一个类中有一个静态方法,它在运行时设置一个对象,如下所述:http://benohead.com/create-anonymous-types-at-runtime-in-c-sharp/
对于新创建的对象,我添加来自不同对象的组合属性,这些对象被发送到我的方法,我在反射中设置值并返回新创建的对象。所有值似乎都有值(到目前为止,我测试了 string 和 int) - 但值在那里。
问题是当我将 DateTime 值设置为 DateTime 属性时 - 返回的值是 01/01/0001 而不是我设置的日期。
这是在反射中设置值的代码:
foreach (string key in values.Keys)
{
if (sqlParams == null || sqlParams.Contains(key))
{
PropertyValue propertyValue = values[key];
object val = propertyValue.Value;
if (val == null)
val = getDefaultValue(propertyValue.PropertyType);
else if (propertyValue.PropertyType == typeof(DateTime) && (DateTime)propertyValue.Value == DateTime.MinValue)
val = new DateTime(1982, 5, 6);// (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue;
myType.GetProperty(key).SetValue(obj, val);
}
}
为什么没有正确返回 DateTime 值?
编辑
完整代码:
private static object createDummyObject(Dictionary<string, PropertyValue> values, List<string> sqlParams)
{
// Code for creating .NET objects at runtime thanks to:
// http://benohead.com/create-anonymous-types-at-runtime-in-c-sharp/
AssemblyBuilder dynamicAssembly =
AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Poco.Sql.Assembly"),
AssemblyBuilderAccess.Run);
ModuleBuilder dynamicModule = dynamicAssembly.DefineDynamicModule("Poco.Sql.Module");
TypeBuilder dynamicType = dynamicModule.DefineType("Poco.Sql.DynamicType", TypeAttributes.Public);
foreach(string key in values.Keys)
{
if (sqlParams == null || sqlParams.Contains(key))
{
PropertyValue propertyValue = values[key];
addProperty(dynamicType, key, propertyValue.PropertyType);
}
}
Type myType = dynamicType.CreateType();
object obj = Activator.CreateInstance(myType);
foreach (string key in values.Keys)
{
if (sqlParams == null || sqlParams.Contains(key))
{
PropertyValue propertyValue = values[key];
object val = propertyValue.Value;
if (val == null)
val = getDefaultValue(propertyValue.PropertyType);
else if (propertyValue.PropertyType == typeof(DateTime) && (DateTime)propertyValue.Value == DateTime.MinValue)
val = new DateTime(1982, 5, 6);// (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue;
myType.GetProperty(key).SetValue(obj, val);
}
}
return obj;
}
private static void addProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType)
{
const MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private);
PropertyBuilder property = typeBuilder.DefineProperty(propertyName, System.Reflection.PropertyAttributes.None, propertyType, new[] { propertyType });
MethodBuilder getMethodBuilder = typeBuilder.DefineMethod("get_value", getSetAttr, propertyType, Type.EmptyTypes);
ILGenerator getIl = getMethodBuilder.GetILGenerator();
getIl.Emit(OpCodes.Ldarg_0);
getIl.Emit(OpCodes.Ldfld, field);
getIl.Emit(OpCodes.Ret);
MethodBuilder setMethodBuilder = typeBuilder.DefineMethod("set_value", getSetAttr, null, new[] { propertyType });
ILGenerator setIl = setMethodBuilder.GetILGenerator();
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Stfld, field);
setIl.Emit(OpCodes.Ret);
property.SetGetMethod(getMethodBuilder);
property.SetSetMethod(setMethodBuilder);
}
private static object getDefaultValue(Type t)
{
if (t == typeof(DateTime))
return DateTime.MinValue;
else if (t.IsValueType)
return Activator.CreateInstance(t);
return null;
}
以及上面代码中使用的 PropertyValue 类:
class PropertyValue
{
public object Value { get; set; }
public Type PropertyType { get; set; }
}
【问题讨论】:
-
请展示一个简短但完整的程序来说明问题。如果我们能重现问题,帮助您会容易得多。
-
我的通灵能力告诉我,您生成的代码在
struct类型和装箱方面存在问题,但由于您的问题不包括相关代码,因此他们可以帮助您。 -
我已经添加了上面的代码
-
太棒了!您能否缩短代码,以便仅保留重现问题所需的部分?确保它仍然可以自行编译...
-
当您使用调试器单步执行此代码时会发生什么?
propertyValue.PropertyType的值是多少?propertyValue.PropertyType == typeof(DateTime)?(DateTime)propertyValue.Value == DateTime.MinValue?
标签: c# .net datetime reflection