ChatGPT解决这个技术问题 Extra ChatGPT

可空对象必须有一个值

异常描述中有一个悖论:Nullable object must have a value (?!)

这就是问题:

我有一个 DateTimeExtended 类,它有

{
  DateTime? MyDataTime;
  int? otherdata;

}

和一个构造函数

DateTimeExtended(DateTimeExtended myNewDT)
{
   this.MyDateTime = myNewDT.MyDateTime.Value;
   this.otherdata = myNewDT.otherdata;
}

运行此代码

DateTimeExtended res = new DateTimeExtended(oldDTE);

抛出 InvalidOperationException 并显示以下消息:

可空对象必须有一个值。

myNewDT.MyDateTime.Value - 有效且包含常规 DateTime 对象。

此消息的含义是什么,我做错了什么?

请注意,oldDTE 不是 null。我已从 myNewDT.MyDateTime 中删除了 Value,但由于生成的 setter 引发了相同的异常。

另一个构造函数是什么?
奇怪的。我在那里用 .Value 重现了异常,没有 .Value 那里没有异常。你确定你正在运行更新的代码吗?
构造函数采用自身的一个实例。你是如何创建第一个实例的?
它被构造为没有参数的 new() ,然后我添加了值(它有效)。
问题解决了 - 问题不存在......有一个生成的其他数据和MyDateTime的设置器,它在设置它之前检查值..当它为空时飞行!

M
Matt

您应该将第 this.MyDateTime = myNewDT.MyDateTime.Value; 行更改为 this.MyDateTime = myNewDT.MyDateTime;

您收到的异常是在 Nullable DateTime.Value 属性中引发的,因为它需要返回一个 DateTime(因为这就是合同对于 .Value 个状态),但它不能这样做,因为没有 DateTime 可以返回,因此它会引发异常。

一般来说,对可空类型盲目调用 .Value 是个坏主意,除非您事先知道该变量 必须 包含一个值(即通过 .HasValue< /strong> 检查)。

编辑

以下是不引发异常的 DateTimeExtended 代码:

class DateTimeExtended
{
    public DateTime? MyDateTime;
    public int? otherdata;

    public DateTimeExtended() { }

    public DateTimeExtended(DateTimeExtended other)
    {
        this.MyDateTime = other.MyDateTime;
        this.otherdata = other.otherdata;
    }
}

我是这样测试的:

DateTimeExtended dt1 = new DateTimeExtended();
DateTimeExtended dt2 = new DateTimeExtended(dt1);

other.MyDateTime 上添加 .Value 会导致异常。删除它可以消除异常。我想你找错地方了。


您对 .value 的看法是正确的,但其他原因会导致异常。我已经删除了 .value,并且我已经更改了构造函数的代码顺序 - 首先复制 int 值,但抛出了相同的异常。
我已经对这个问题发表了评论 - 发现了问题,它在为属性生成的设置器中。
是的,它解决了我的问题,我只是将可空对象更改为不可空对象,并将日期时间直接转换为字符串,而不是通过 datetimeobject.value.datetime.tostring()
很好的答案。在 null 对象上调用 .Value 异常是有道理的(我猜),但是如果您碰巧正在处理两个 Nullable 对象,那么异常消息确实会产生误导。像“.Value 属性要求对象为非空”之类的东西会更有意义。
P
Protector one

使用 LINQ 扩展方法(例如 SelectWhere)时,lambda 函数可能会转换为 SQL,其行为可能与您的 C# 代码不同。例如,C# 的短路评估 &&|| 被转换为 SQL 的急切 ANDOR。当您在 lambda 中检查 null 时,这可能会导致问题。

例子:

MyEnum? type = null;
Entities.Table.Where(a => type == null || 
    a.type == (int)type).ToArray();  // Exception: Nullable object must have a value

我意识到这个答案与 OP 的具体情况无关,但与他得到的异常有关。此外,此页面是该异常在 Google 上的第一次点击,这使其具有相关性。
这也是我使用空条件运算符(Javascript 中的“可选链接”)的问题。而不是 obj?.getValue(),我需要做 obj != null && obj.getValue()
A
ArunPratap

尝试删除 .value

DateTimeExtended(DateTimeExtended myNewDT)
{
   this.MyDateTime = myNewDT.MyDateTime;
   this.otherdata = myNewDT.otherdata;
}

没有帮助。如果我先运行第二行,它会引发相同的异常。
C
Cecil Has a Name

不使用 .Value 部分直接分配成员:

DateTimeExtended(DateTimeExtended myNewDT)
{
   this.MyDateTime = myNewDT.MyDateTime;
   this.otherdata = myNewDT.otherdata;
}

L
Lee

在这种情况下,oldDTE 为空,因此当您尝试访问 oldDTE.Value 时,会抛出 InvalidOperationException,因为没有值。在您的示例中,您可以简单地执行以下操作:

this.MyDateTime = newDT.MyDateTime;

oldDTE 不为空,但无论如何我删除了该值......它仍然抛出那个异常......
P
Pavel Radzivilovsky

看起来 oldDTE.MyDateTime 是空的,所以构造函数试图取它的值 - 它抛出了。


J
Juris

尝试访问空值对象的值时收到此消息。

sName = myObj.Name;

这会产生错误。首先你应该检查对象是否不为空

if(myObj != null)
  sName = myObj.Name;

这行得通。


在回答之前,请先尝试通读该问题的其他答案 - 尤其是已接受的答案,该答案准确地说明了您在 your 答案中放置的内容。虽然它没有使用代码显示它,但它拼写出来。此外,请尝试使您的示例代码与问题相关 - 例如 this.MyDateTime = myNewDT.MyDateTime.Value;,而不是 sName = myObj.Name;
K
KKG

我得到了这个解决方案,它对我有用

if (myNewDT.MyDateTime == null)
{
   myNewDT.MyDateTime = DateTime.Now();
}