C# 确定日期时间和日期时间之间的区别?(可为空)

本文关键字:时间 日期 之间 区别 | 更新日期: 2023-09-27 18:31:54

我正在尝试使用反射来确定日期时间和日期时间之间的区别。 请在下面查看我的测试代码:

    public class TestClass
    {
        public DateTime testDate1 { get; set; }
        public DateTime? testDate2 { get; set; }
    }
    public void Test()
    {
        TestClass testing = new TestClass();
        var props = typeof(TestClass).GetProperties();
        foreach (PropertyInfo p in props)
        {
            object o = p.GetValue(testing);
            if (typeof(DateTime?).IsInstanceOfType(o))
            {
                o = DateTime.Now;
            }
            if (typeof(DateTime).IsInstanceOfType(o))
            {
                if (((DateTime)o) == DateTime.MinValue)
                {
                    o = null;
                }
            }
            Console.WriteLine(string.Format("{0} = {1}", p.Name, (o ?? "NULL").ToString()));
        }
    }

此代码的输出与我的预期相反。 目前输出为:

testDate1 = 26/01/2016 16:15:00

测试日期2 = 空

我希望 testDate1 为空,而 testDate2 包含该值。

调试此代码时,似乎使用 testDate1 的第一次传递传递了两种类型的 if 语句,第二次传递了两个 if 语句。 任何人都可以帮助我理解并希望尝试捕获日期时间的特定可为空的实例吗?

请注意,为了以防万一,我还尝试切换到 Nullable 的定义和测试,但这没有区别。

非常感谢!

C# 确定日期时间和日期时间之间的区别?(可为空)

首先,请记住,testDate1永远不能为空,因为DateTime是一个结构体。如果在不初始化的情况下声明DateTime,它将获得默认值 DateTime.MinValue 。 另一方面,testDate2是一个可为 Null 的结构,其中默认值为 null(-ish...它实际上是一个表示 null 的值,但不是 null 本身)。

IsInstanceOfType 在后台使用 oGetType() 方法来验证其类型是否与您正在比较的类型相同(在本例中为 DateTime? )。但是,如果您查看文档,它会指出:

在可为 Null 的类型上调用 GetType 会导致在类型隐式转换为 Object 时执行装箱操作。因此,GetType 始终返回一个表示基础类型的 Type 对象,而不是 Nullable 类型。

因此,如果您单步执行 testDate1 属性的 foreach 循环,您将看到第一个条件将返回 true(因为testDate1不能为 null,这意味着它必须是 DateTime 类型)。然后,您进入第二个 if 条件(尽管这实际上只是再次执行相同的检查),但您不会进入内部 if,因为o当前值为 DateTime.Now

现在逐步执行testDate2(它保存一个 null 值),您将看到您没有输入任何 if 条件,因为 null 没有类型。因此,您的对象将在循环的第二次迭代中保持 null,从而为您提供在那里看到的输出。


注意:正如您所知,您向o"分配"值的方式根本不会修改原始 TestClass。请考虑以下事项:

TestClass testing = new TestClass();
var prop = typeof(TestClass).GetProperty("testDate1");
// Here we get the current value of testing.testDate1, which is the default DateTime.MinValue
object o = prop.GetValue(testing);
// Here we set o to null... has ZERO effect on testing.testDate1. 
o = null;
// What you actually want is probably the following.
// (Remember though that testDate1 can't be null... this just sets it back to DateTime.MinValue.)
prop.SetValue(testing, null);

答案是你不能。

如果你有一个object date,就没有办法知道它是否来自一个无DateTime

DateTime? nullable = DateTime.Now;
object o = nullable;

o的分配在道德上等同于

object temp = null;
if (nullable.HasValue)
{
    temp = nullable.Value;
}
o = temp;

如您所见,可为空类型的信息丢失,您真正得到的是盒装可为空的值。

这很容易通过简单地执行o.GetType()如果 nullable 具有值,它将返回DateTime,如果没有,您将获得NullReferenceException

这并不意味着您无法确定属性、方法或成员的声明类型是否可为空。您可以通过反射轻松做到这一点。

感谢您提供如此多有用的评论和链接。 我意识到这是我应该检查的财产,而不是对象。 我正在使用这个:

Nullable.GetUnderlyingType(p.PropertyType)

它允许我确定我正在处理什么并且非常有效。 我最终仍然打开类型(T)。名字,但当我来到那座桥时,我会过那座桥:)

我必须接受这样一个事实,即函数式代码与丑陋的代码仍然是一场内部斗争!