可空对象必须有一个值

发布于 2024-08-15 05:41:10 字数 787 浏览 2 评论 0原文

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

这就是问题:

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

云醉月微眠 2024-08-22 05:41:10

您应该将 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);

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

You should change the line this.MyDateTime = myNewDT.MyDateTime.Value; to just this.MyDateTime = myNewDT.MyDateTime;

The exception you were receiving was thrown in the .Value property of the Nullable DateTime, 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.

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:

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.

丑丑阿 2024-08-22 05:41:10

使用 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

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.

Example:

MyEnum? type = null;
Entities.Table.Where(a => type == null || 
    a.type == (int)type).ToArray();  // Exception: Nullable object must have a value
听你说爱我 2024-08-22 05:41:10

尝试删除 .value

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

Try dropping the .value

DateTimeExtended(DateTimeExtended myNewDT)
{
   this.MyDateTime = myNewDT.MyDateTime;
   this.otherdata = myNewDT.otherdata;
}
才能让你更想念 2024-08-22 05:41:10

为了回答您的实际问题,“可为空对象必须有一个值”是什么意思?

它实际上是在说“您正在尝试获取可为空对象的 .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"

凡尘雨 2024-08-22 05:41:10

直接分配成员,无需 .Value 部分:

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

Assign the members directly without the .Value part:

DateTimeExtended(DateTimeExtended myNewDT)
{
   this.MyDateTime = myNewDT.MyDateTime;
   this.otherdata = myNewDT.otherdata;
}
够运 2024-08-22 05:41:10

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

this.MyDateTime = newDT.MyDateTime;

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:

this.MyDateTime = newDT.MyDateTime;
秋意浓 2024-08-22 05:41:10

使用

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

它会简单地检查值,如果没有值则设置 Null。

> .Value

仅当您确定它即将到来时才可以使用。
但由于您不确定,您只需使用“.GetValueOrDefault()”

说明:

  1. DateTimeExtended(DateTimeExtended myNewDT)DateTimeExtended< 的构造函数/code> 类,它采用另一个 DateTimeExtended 对象 myNewDT 作为参数。


  2. this.MyDateTime = myNewDT.MyDateTime.GetValueOrDefault(); 分配
    myNewDT.MyDateTime 的值赋值给当前实例的 MyDateTime 属性。GetValueOrDefault() 用于安全处理
    myNewDT.MyDateTime 可能为 null 的情况。如果
    myNewDT.MyDateTime 为 null,此方法将返回默认值
    DateTime 类型的值(即 DateTime.MinValue)。

  3. this.otherdata = myNewDT.otherdata; 使用 myNewDT.otherdata` 中的值分配当前实例的 otherdata 属性,假设其他数据是非可为 null 的属性。

此构造函数旨在确保新实例的 MyDateTime 属性永远不为 null。如果 myNewDT.MyDateTime 为 null,它会为 MyDateTime 分配一个默认值,这样当您不确定 myNewDT.MyDateTime 是否存在时,可以更安全地使用代码。是否有价值。

Use

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

It'll simply check the value and set Null if there is no value.

> .Value

Must only be used when you are sure it's coming.
But as you are not sure, you simply use ".GetValueOrDefault()"

Explanation:

  1. DateTimeExtended(DateTimeExtended myNewDT) is a constructor for the DateTimeExtended class, which takes another DateTimeExtended object myNewDT as a parameter.

  2. this.MyDateTime = myNewDT.MyDateTime.GetValueOrDefault(); assigns
    the value of myNewDT.MyDateTime to the MyDateTime property of the current instance.GetValueOrDefault() is used to safely handle
    situations where myNewDT.MyDateTime might be null. If
    myNewDT.MyDateTime is null, this method will return the default
    value for the DateTime type (which is DateTime.MinValue).

  3. this.otherdata = myNewDT.otherdata; assigns the otherdata 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 to MyDateTime if myNewDT.MyDateTime is null, making the code safer to use when you are not sure whether myNewDT.MyDateTime will have a value or not.

心是晴朗的。 2024-08-22 05:41:10

看起来 oldDTE.MyDateTime 为 null,因此构造函数尝试获取它的 Value - 结果抛出。

Looks like oldDTE.MyDateTime was null, so constructor tried to take it's Value - which threw.

我一直都在从未离去 2024-08-22 05:41:10

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

sName = myObj.Name;

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

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

这有效。

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.

别忘他 2024-08-22 05:41:10

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

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

I got this solution and it is working for me

if (myNewDT.MyDateTime == null)
{
   myNewDT.MyDateTime = DateTime.Now();
}
早乙女 2024-08-22 05:41:10

我使用 EF Core 7.x 遇到此异常:

System.InvalidOperationException:可为 Null 的对象必须有一个值。

使用此代码:

Updated = new[] { x.Updated, x.Threats.Max(tac => tac.Updated) }.Max()

new[] 更改为 List 然后它起作用了:

Updated = new List<DateTime?> { x.Updated, x.Threats.Max(tac => tac.Updated) }.Max()

I got this exception using EF Core 7.x:

System.InvalidOperationException: Nullable object must have a value.

With this code:

Updated = new[] { x.Updated, x.Threats.Max(tac => tac.Updated) }.Max()

Changed new[] to List<DateTime?> and then it worked:

Updated = new List<DateTime?> { x.Updated, x.Threats.Max(tac => tac.Updated) }.Max()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文