C# 可为空的对象必须有一个值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1896185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
nullable object must have a value
提问by Dani
There is paradox in the exception description: Nullable object must have a value (?!)
异常描述中有悖论:可空对象必须有值(?!)
This is the problem:
这就是问题:
I have a DateTimeExtended
class,
that has
我有一DateTimeExtended
堂课,那有
{
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:
抛出一个InvalidOperationException
消息:
Nullable object must have a value.
可为空的对象必须有一个值。
myNewDT.MyDateTime.Value
- is valid and contain a regular DateTime
object.
myNewDT.MyDateTime.Value
- 有效并且包含一个常规DateTime
对象。
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.
请注意,oldDTE
不是null
。我已经删除了Value
frommyNewDT.MyDateTime
但由于生成的 setter 引发了相同的异常。
采纳答案by Yuliy
You should change the line this.MyDateTime = myNewDT.MyDateTime.Value;
to just this.MyDateTime = myNewDT.MyDateTime;
你应该行改变this.MyDateTime = myNewDT.MyDateTime.Value;
,只是this.MyDateTime = myNewDT.MyDateTime;
The exception you were receiving was thrown in the .Value
property of the NullableDateTime
, as it is required to return a DateTime
(since that's what the contract for .Value
states), but it can't do so because there's no DateTime
to return, so it throws an exception.
您收到的异常.Value
是在Nullable的属性中抛出的DateTime
,因为它需要返回一个DateTime
(因为这是.Value
状态合同),但它不能这样做,因为没有DateTime
返回,所以它抛出了一个异常。
In general, it is a bad idea to blindly call .Value
on a nullable type, unless you have some prior knowledge that that variable MUSTcontain a value (i.e. through a .HasValue
check).
通常,盲目调用.Value
可空类型是一个坏主意,除非您事先知道该变量必须包含一个值(即通过.HasValue
检查)。
EDIT
编辑
Here's the code for DateTimeExtended
that does not throw an exception:
这DateTimeExtended
是不引发异常的代码:
class DateTimeExtended
{
public DateTime? MyDateTime;
public int? otherdata;
public DateTimeExtended() { }
public DateTimeExtended(DateTimeExtended other)
{
this.MyDateTime = other.MyDateTime;
this.otherdata = other.otherdata;
}
}
I tested it like this:
我是这样测试的:
DateTimeExtended dt1 = new DateTimeExtended();
DateTimeExtended dt2 = new DateTimeExtended(dt1);
Adding the .Value
on other.MyDateTime
causes an exception. Removing it gets rid of the exception. I think you're looking in the wrong place.
添加.Value
onother.MyDateTime
会导致异常。删除它可以消除异常。我认为你找错地方了。
回答by Paul Creasey
Try dropping the .value
尝试删除 .value
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime;
this.otherdata = myNewDT.otherdata;
}
回答by Cecil Has a Name
Assign the members directly without the .Value
part:
直接分配成员,不带.Value
部件:
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime;
this.otherdata = myNewDT.otherdata;
}
回答by Lee
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:
在这种情况下,oldDTE 为空,因此当您尝试访问 oldDTE.Value 时,会抛出 InvalidOperationException,因为没有值。在您的示例中,您可以简单地执行以下操作:
this.MyDateTime = newDT.MyDateTime;
回答by Pavel Radzivilovsky
Looks like oldDTE.MyDateTime was null, so constructor tried to take it's Value - which threw.
看起来 oldDTE.MyDateTime 是空的,所以构造函数试图取它的值 - 抛出。
回答by Juris
I got this message when trying to access values of a null valued object.
尝试访问空值对象的值时收到此消息。
sName = myObj.Name;
this will produce error. First you should check if object not null
这会产生错误。首先你应该检查对象是否不为空
if(myObj != null)
sName = myObj.Name;
This works.
这有效。
回答by Protector one
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 eager AND
and OR
. This can cause problems when you're checking for null in your lambda.
使用 LINQ 扩展方法(例如Select
, Where
)时,lambda 函数可能会转换为 SQL,其行为可能与您的 C# 代码不同。例如,C# 的短路求值&&
并||
转换为 SQL 的 EagerAND
和OR
. 当您在 lambda 中检查 null 时,这可能会导致问题。
Example:
例子:
MyEnum? type = null;
Entities.Table.Where(a => type == null ||
a.type == (int)type).ToArray(); // Exception: Nullable object must have a value