nullable 객체는 값을 가져야합니다


190

예외 설명에 역설이 있습니다. Nullable 객체에는 값 (?!)이 있어야합니다.

이게 문제 야:

나는이 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에서를 제거 myNewDT.MyDateTime했지만 생성 된 setter로 인해 동일한 예외가 발생합니다.


다른 생성자는 무엇입니까?
Paul Creasey

이상한. .Value가있는 예외를 재현하고 .Value가 없으면 예외가 없습니다. 업데이트 된 코드를 실행하고 있습니까?
Yuliy

생성자는 자체 인스턴스를 가져옵니다. 첫 번째 인스턴스를 어떻게 작성하고 있습니까?
Paul Creasey

매개 변수없이 new ()로 구성 된 다음 값을 추가합니다 (작동합니다).
Dani

6
문제가 해결되었습니다-문제가 없었습니다 ... 설정하기 전에 값을 확인하는 otherdata 및 MyDateTime에 생성자가 생성되었습니다. null 일 때 비행 !!!
Dani

답변:


201

this.MyDateTime = myNewDT.MyDateTime.Value;을 그냥 변경해야합니다this.MyDateTime = myNewDT.MyDateTime;

당신이 수신 있었던 예외에 던져진 .Value의 특성 Null 허용 DateTime 반환해야 한, DateTime(대한 그 이후 어떤 계약 .Value상태),하지만 거기에 있기 때문에 그렇게 할 수 없어 DateTime반환에 예외를 throw 있도록.

일반적으로 .Value변수 에 값이 있어야 한다는 사전 지식이없는 한 (예 : .HasValue검사를 통해 ) 맹목적으로 nullable 형식을 호출하는 것은 좋지 않습니다 .

편집하다

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);

.Valueon을 추가하면 other.MyDateTime예외가 발생합니다. 제거하면 예외가 제거됩니다. 당신이 잘못된 곳을보고 있다고 생각합니다.


당신은 .value에 대해 맞지만 다른 어떤 것이 예외를 일으 킵니다. .value를 제거하고 생성자의 코드 순서를 변경하여 int 값을 먼저 복사하지만 동일한 예외가 발생합니다.
Dani

나는 질문에 대해 논평했다-문제를 발견했다, 그것은 속성에 대한 생성 된 세터에 있었다.
Dani

예, 문제가 해결되었습니다. null 가능 객체를 null이 아닌 객체로 변경하고 datetimeobject.value.datetime.tostring ()이 아니라 datetime을 문자열로 직접 변환합니다.
adnan

좋은 대답입니다. .Valuenull 객체를 호출하는 예외를 얻는 것이 의미가 있지만 (Nullable) 두 개의 객체를 처리하는 경우 예외 메시지가 실제로 오도됩니다. '.Value 속성은 객체가 null이 아닌 것을 요구합니다'와 같은 것이 훨씬 더 의미가 있습니다.
DVK

9

(예를 들어 LINQ 확장 방법을 사용하는 경우 Select, Where), 람다 함수는 당신의 C # 코드에 동일하게 작동하지 않을 수 있습니다 그 SQL로 변환 할 수 있습니다. 예를 들어, C #의 단락 회로 평가 &&와는 ||SQL의 열망로 변환 AND하고 OR. 람다에서 null을 확인할 때 문제가 발생할 수 있습니다.

예:

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

5
이 답변은 OP의 특정 사례와 관련이 없지만 그가 얻는 예외와 관련이 있다는 것을 알고 있습니다. 또한이 페이지는 해당 예외에 대해 Google에서 처음으로 방문한 것이므로 관련성이 있습니다.
수호자 1

6

떨어 뜨리십시오 .value

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

도움이되지 않습니다. 두 번째 줄을 먼저 실행하면 동일한 예외가 발생합니다.
Dani

2

이 경우 oldDTE는 null이므로 oldDTE.Value에 액세스하려고하면 값이 없으므로 InvalidOperationException이 발생합니다. 귀하의 예에서 간단하게 할 수 있습니다 :

this.MyDateTime = newDT.MyDateTime;

oldDTE는 null이 아니지만 어쨌든 값을 제거했습니다 ... 여전히 예외가 발생합니다 ....
Dani

1

.Value파트 없이 멤버를 직접 지정하십시오 .

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


0

null 값을 가진 개체의 값에 액세스하려고 할 때이 메시지가 나타납니다.

sName = myObj.Name;

오류가 발생합니다. 먼저 객체가 null이 아닌지 확인해야합니다

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

작동합니다.


1
응답하기 전에 먼저 질문에 대한 다른 답변을 읽어 보시기 바랍니다 - 상태는 당신이 배치 정확히 어떤 것을 특별히 허용 대답 당신의 대답을. 코드를 사용하여 표시하지는 않지만 철자를 설명합니다. 또한, 질문의 당신의 예제 코드 관련 만들려고 - 같은 this.MyDateTime = myNewDT.MyDateTime.Value;하지,sName = myObj.Name;
newfurniturey

0

나는이 해결책을 얻었고 그것은 나를 위해 일하고있다.

if (myNewDT.MyDateTime == null)
{
   myNewDT.MyDateTime = DateTime.Now();
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.