如何使用Reflection为对象上的所有DateTime属性设置DateTime.Kind

Run*_*ick 23 c# reflection datetime

在我的应用程序中,我通过Web服务检索域对象.在Web服务数据中,我知道所有日期值都是UTC,但Web服务不会将其xs:dateTime值格式化为UTC日期.(换句话说,该字母Z不会附加到每个日期的末尾以表示UTC.)

我无法在此时更改Web服务的行为方式,但作为一种解决方法,我创建了一个方法,在Web服务中的对象被反序列化后立即调用该方法.

    private void ExplicitlyMarkDateTimesAsUtc<T>(T obj) where T : class
    {
        Type t = obj.GetType();

        // Loop through the properties.
        PropertyInfo[] props = t.GetProperties();
        for (int i = 0; i < props.Length; i++)
        {
            PropertyInfo p = props[i];
            // If a property is DateTime or DateTime?, set DateTimeKind to DateTimeKind.Utc.
            if (p.PropertyType == typeof(DateTime))
            {
                DateTime date = (DateTime)p.GetValue(obj, null);
                date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
                p.SetValue(obj, date, null);
            }
            // Same check for nullable DateTime.
            else if (p.PropertyType == typeof(Nullable<DateTime>))
            {
                DateTime? date = (DateTime?)p.GetValue(obj, null);
                DateTime? newDate = DateTime.SpecifyKind(date.Value, DateTimeKind.Utc);
                p.SetValue(obj, newDate, null);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

该方法以一个对象,并通过它的属性循环,发现要么是属性DateTimeNullable<DateTime>,然后(应该)显式地设定DateTime.Kind为每个属性值的属性DateTimeKind.Utc.

代码不会抛出任何异常,但obj永远不会更改其DateTime属性.在调试器p.SetValue(obj, date, null);中调用,但obj永远不会被修改.

为什么没有应用更改obj

Han*_*ant 31

我尝试时工作正常.请注意,你只是在改变种类,而不是时间.并且您没有正确处理空日期,如果date.HasValue为false,则不能使用date.Value.确保不会以静默方式捕获异常并绕过其余的属性分配.固定:

            // Same check for nullable DateTime.
            else if (p.PropertyType == typeof(Nullable<DateTime>)) {
                DateTime? date = (DateTime?)p.GetValue(obj, null);
                if (date.HasValue) {
                    DateTime? newDate = DateTime.SpecifyKind(date.Value, DateTimeKind.Utc);
                    p.SetValue(obj, newDate, null);
                }
            }
Run Code Online (Sandbox Code Playgroud)