我这样存储更新操作:

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.ValueDateTime,而不是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/

10-17 01:56