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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:42:21  来源:igfitidea点击:

nullable object must have a value

c#nullableinvalidoperationexception

提问by Dani

There is paradox in the exception description: Nullable object must have a value (?!)

异常描述中有悖论:可空对象必须有值(?!)

This is the problem:

这就是问题:

I have a DateTimeExtendedclass, 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 InvalidOperationExceptionwith the message:

抛出一个InvalidOperationException消息:

Nullable object must have a value.

可为空的对象必须有一个值。

myNewDT.MyDateTime.Value- is valid and contain a regular DateTimeobject.

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

What is the meaning of this message and what am I doing wrong?

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

Note that oldDTEis not null. I've removed the Valuefrom myNewDT.MyDateTimebut the same exception is thrown due to a generated setter.

请注意,oldDTE不是null。我已经删除了ValuefrommyNewDT.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 .Valueproperty of the NullableDateTime, as it is required to return a DateTime(since that's what the contract for .Valuestates), but it can't do so because there's no DateTimeto return, so it throws an exception.

您收到的异常.Value是在Nullable的属性中抛出的DateTime,因为它需要返回一个DateTime(因为这是.Value状态合同),但它不能这样做,因为没有DateTime返回,所以它抛出了一个异常。

In general, it is a bad idea to blindly call .Valueon a nullable type, unless you have some prior knowledge that that variable MUSTcontain a value (i.e. through a .HasValuecheck).

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

EDIT

编辑

Here's the code for DateTimeExtendedthat 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 .Valueon other.MyDateTimecauses an exception. Removing it gets rid of the exception. I think you're looking in the wrong place.

添加.Valueonother.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 .Valuepart:

直接分配成员,不带.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 ANDand OR. This can cause problems when you're checking for null in your lambda.

使用 LINQ 扩展方法(例如Select, Where)时,lambda 函数可能会转换为 SQL,其行为可能与您的 C# 代码不同。例如,C# 的短路求值&&||转换为 SQL 的 EagerANDOR. 当您在 lambda 中检查 null 时,这可能会导致问题。

Example:

例子:

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