我这样存储更新操作:
class Update
{
public Expression MemberExpression { get; set; }
public Type FieldType { get; set; }
public object NewValue { get; set; }
}
例如:
var myUpdate = new Update
{
MemberExpression = (MyType o) => o.LastModified,
FieldType = typeof(DateTime?),
NewValue = (DateTime?)DateTime.Now
}
然后,我尝试稍后(简化)应用此更新:
var lambda = myUpdate.MemberExpression as LambdaExpression;
var memberExpr = lambda.Body as MemberExpression;
var prop = memberExpr.Member as PropertyInfo;
prop.SetValue(item, myUpdate.Value);
但是,
myUpdate.Value
是DateTime
,而不是DateTime?
。这是因为当您将空变量强制转换为object
时,它要么变为null
要么将值类型装箱。由于
(DateTime?)myUpdate.Value
可以将其恢复为正确的类型,因此我尝试使用Convert.ChangeType
模拟此编译时构造。但是,它说从DateTime
转换为DateTime?
是不可能的。我在这里可以使用哪种方法将对象恢复为原始类型?
有什么方法可以在单个字段中存储可为空的类型,常规结构和常规对象,然后将确切的内容再次存储回去?
最佳答案
如果在创建myUpdate时知道表达式的类型,即使装箱/拆箱,SetInfo()
也会正确设置数据。
public class Update
{
public Expression MemberExpression { get; set; }
public Type ClassType { get; set; }
public object NewValue { get; set; }
}
public class MyType
{
public DateTime? LastModified { get; set; }
}
void Main()
{
var myUpdate = new Update
{
MemberExpression =
(Expression<Func<MyType, DateTime?>>)((MyType o) => o.LastModified),
ClassType = typeof(MyType),
NewValue = DateTime.Now
};
// At a later point where we do not want to instantiate via strong typing
var item = Activator.CreateInstance(myUpdate.ClassType);
var lambda = myUpdate.MemberExpression as LambdaExpression;
var memberExpr = lambda.Body as MemberExpression;
var prop = memberExpr.Member as PropertyInfo;
prop.SetValue(item, myUpdate.NewValue);
item.Dump();
}
正确地输出与创建日期相对应的DateTime值,没有异常(exception)。
关于c# - 取消装箱可空类型-解决方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30404238/