我在一个类中有一个静态方法,它在运行时设置一个对象,如下所述:http://benohead.com/create-anonymous-types-at-runtime-in-c-sharp/
对于新创建的对象,我添加了从发送到我的方法的不同对象组合的属性,并在反射中设置值并返回新创建的对象。所有值似乎都有值(到目前为止我测试了字符串和整数) - 但值都在那里。
问题是当我将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; }
}
答案 0 :(得分:0)
问题可能在这里?
private static object getDefaultValue(Type t)
{
if (t == typeof(DateTime))
return DateTime.MinValue;
else if (t.IsValueType)
return Activator.CreateInstance(t);
return null;
}
日期存储为64位带符号的整数,表示从01/01/0001 12:00开始的“滴答”数(1滴= 100纳秒)。当您致电DateTime.MinValue
时,输出为01/01/0001。