异常描述中有悖论:可空对象必须有值(?!)
这就是问题:
我有一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
。我已经删除了Value
frommyNewDT.MyDateTime
但由于生成的 setter 引发了相同的异常。
你应该行改变this.MyDateTime = myNewDT.MyDateTime.Value;
,只是this.MyDateTime = myNewDT.MyDateTime;
你收到的异常.Value
是在Nullable 的属性中抛出的DateTime
,因为它需要返回一个DateTime
(因为这是.Value
状态合同),但它不能这样做,因为没有DateTime
返回,所以它抛出了一个异常。
通常,盲目调用.Value
可空类型是一个坏主意,除非你事先知道该变量必须包含一个值(即通过.HasValue
检查)。
编辑
这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);
添加.Value
onother.MyDateTime
会导致异常。删除它可以消除异常。我认为你找错地方了。
您对 .value 的看法是正确的,但其他原因会导致异常。我删除了 .value,并更改了构造函数的代码顺序 - 首先复制 int 值,但抛出了相同的异常。
我已经对这个问题发表了评论 - 发现了问题,它在属性的生成设置器中。
是的,它解决了我的问题,我只是将空对象更改为非空对象,并将日期时间直接转换为字符串,而不是通过 datetimeobject.value.datetime.tostring()
很好的答案。
.Value
在 null 对象上调用异常是有道理的(我猜),但是如果您碰巧处理两个 Nullable 对象,则异常消息确实具有误导性。诸如“.Value 属性要求对象为非空”之类的东西会更有意义。