可空对象必须有一个值
异常描述中有一个悖论: 可空对象必须有一个值(?!)
这就是问题:
我有一个 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
,但由于生成的设置器而引发了相同的异常。
There is paradox in the exception description:
Nullable object must have a value (?!)
This is the problem:
I have a DateTimeExtended
class,
that has
{
DateTime? MyDataTime;
int? otherdata;
}
and a constructor
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime.Value;
this.otherdata = myNewDT.otherdata;
}
running this code
DateTimeExtended res = new DateTimeExtended(oldDTE);
throws an InvalidOperationException
with the message:
Nullable object must have a value.
myNewDT.MyDateTime.Value
- is valid and contain a regular DateTime
object.
What is the meaning of this message and what am I doing wrong?
Note that oldDTE
is not null
. I've removed the Value
from myNewDT.MyDateTime
but the same exception is thrown due to a generated setter.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
您应该将
this.MyDateTime = myNewDT.MyDateTime.Value;
行更改为this.MyDateTime = myNewDT.MyDateTime;
您收到的异常是在
.Value
NullableDateTime
属性,因为需要返回DateTime
(因为这是.Value
的约定),但它不能这样做,因为没有DateTime
返回,所以它会抛出异常。一般来说,盲目地在可空类型上调用
.Value
是一个坏主意,除非您事先知道该变量必须包含一个值(即通过 <强>.HasValue
检查)。编辑
这是不引发异常的
DateTimeExtended
代码:我像这样测试了它:
在
other上添加
导致异常。删除它可以消除异常。我认为你找错地方了。.Value
。 MyDateTimeYou should change the line
this.MyDateTime = myNewDT.MyDateTime.Value;
to justthis.MyDateTime = myNewDT.MyDateTime;
The exception you were receiving was thrown in the
.Value
property of the NullableDateTime
, as it is required to return aDateTime
(since that's what the contract for.Value
states), but it can't do so because there's noDateTime
to return, so it throws an exception.In general, it is a bad idea to blindly call
.Value
on a nullable type, unless you have some prior knowledge that that variable MUST contain a value (i.e. through a.HasValue
check).EDIT
Here's the code for
DateTimeExtended
that does not throw an exception:I tested it like this:
Adding the
.Value
onother.MyDateTime
causes an exception. Removing it gets rid of the exception. I think you're looking in the wrong place.使用 LINQ 扩展方法(例如
Select
、Where
)时,lambda 函数可能会转换为 SQL,其行为可能与 C# 代码不同。例如,C# 的短路计算&&
和||
被转换为 SQL 的急切AND
和OR
>。当您在 lambda 中检查 null 时,这可能会导致问题。例子:
When using LINQ extension methods (e.g.
Select
,Where
), the lambda function might be converted to SQL that might not behave identically to your C# code. For instance, C#'s short-circuit evaluated&&
and||
are converted to SQL's eagerAND
andOR
. This can cause problems when you're checking for null in your lambda.Example:
尝试删除
.value
Try dropping the
.value
为了回答您的实际问题,“可为空对象必须有一个值”是什么意思?
它实际上是在说“您正在尝试获取可为空对象的 .Value,但它为 null,因此无法完成。”。
我认为这是一个写得很糟糕的错误消息。他们可能只是说“可空对象必须有一个值才能获取它的 .Value”
To answer your actual question, what does "Nullable object must have a value " mean?
It is actually saying "You are trying to take the .Value of a nullable object, but it is null so that can't be done.".
I think that it is a terribly-written error message. They could have just said "Nullable object must have a value in order to take it's .Value"
直接分配成员,无需
.Value
部分:Assign the members directly without the
.Value
part:在这种情况下,oldDTE 为 null,因此当您尝试访问 oldDTE.Value 时,会抛出 InvalidOperationException,因为没有值。在您的示例中,您可以简单地执行以下操作:
In this case oldDTE is null, so when you try to access oldDTE.Value the InvalidOperationException is thrown since there is no value. In your example you can simply do:
使用
它会简单地检查值,如果没有值则设置 Null。
仅当您确定它即将到来时才可以使用。
但由于您不确定,您只需使用“.GetValueOrDefault()”
说明:
DateTimeExtended(DateTimeExtended myNewDT)
是DateTimeExtended< 的构造函数/code> 类,它采用另一个
DateTimeExtended
对象myNewDT
作为参数。this.MyDateTime = myNewDT.MyDateTime.GetValueOrDefault();
分配将
myNewDT.MyDateTime
的值赋值给当前实例的MyDateTime
属性。GetValueOrDefault()
用于安全处理myNewDT
.MyDateTime
可能为 null 的情况。如果myNewDT.MyDateTime
为 null,此方法将返回默认值DateTime
类型的值(即DateTime.MinValue
)。this.otherdata = myNewDT.otherdata;
使用 myNewDT.otherdata` 中的值分配当前实例的otherdata
属性,假设其他数据是非可为 null 的属性。此构造函数旨在确保新实例的
MyDateTime
属性永远不为 null。如果myNewDT.MyDateTime
为 null,它会为MyDateTime
分配一个默认值,这样当您不确定myNewDT.MyDateTime
是否存在时,可以更安全地使用代码。是否有价值。Use
It'll simply check the value and set Null if there is no value.
Must only be used when you are sure it's coming.
But as you are not sure, you simply use ".GetValueOrDefault()"
Explanation:
DateTimeExtended(DateTimeExtended myNewDT)
is a constructor for theDateTimeExtended
class, which takes anotherDateTimeExtended
objectmyNewDT
as a parameter.this.MyDateTime = myNewDT.MyDateTime.GetValueOrDefault();
assignsthe value of
myNewDT.MyDateTime
to theMyDateTime
property of the current instance.GetValueOrDefault()
is used to safely handlesituations where
myNewDT
.MyDateTime
might be null. IfmyNewDT.MyDateTime
is null, this method will return the defaultvalue for the
DateTime
type (which isDateTime.MinValue
).this.otherdata = myNewDT.otherdata;
assigns theotherdata
property of the current instance with the value from myNewDT.otherdata`, assuming that other data is a non-nullable property.This constructor is designed to ensure that the
MyDateTime
property of the new instance is never null. It assigns a default value toMyDateTime
ifmyNewDT.MyDateTime
is null, making the code safer to use when you are not sure whethermyNewDT.MyDateTime
will have a value or not.看起来 oldDTE.MyDateTime 为 null,因此构造函数尝试获取它的 Value - 结果抛出。
Looks like oldDTE.MyDateTime was null, so constructor tried to take it's Value - which threw.
当我尝试访问空值对象的值时收到此消息。
这会产生错误。首先你应该检查对象是否不为空
这有效。
I got this message when trying to access values of a null valued object.
this will produce error. First you should check if object not null
This works.
我得到了这个解决方案,它对我有用
I got this solution and it is working for me
我使用 EF Core 7.x 遇到此异常:
使用此代码:
将
new[]
更改为List
然后它起作用了:I got this exception using EF Core 7.x:
With this code:
Changed
new[]
toList<DateTime?>
and then it worked: