Existe um paradoxo na descrição da exceção: o objeto nulo deve ter um valor (?!)
Este é o problema:
Eu tenho uma DateTimeExtended
aula que tem
{
DateTime? MyDataTime;
int? otherdata;
}
e um construtor
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime.Value;
this.otherdata = myNewDT.otherdata;
}
executando este código
DateTimeExtended res = new DateTimeExtended(oldDTE);
lança um InvalidOperationException
com a mensagem:
Objecto nulo deve ter um valor.
myNewDT.MyDateTime.Value
- é válido e contém um DateTime
objeto regular .
Qual é o significado desta mensagem e o que estou fazendo de errado?
Note que oldDTE
não é null
. Eu removi o Value
de myNewDT.MyDateTime
mas a mesma exceção é lançada devido a um setter gerado.
Respostas:
Você deve alterar a linha
this.MyDateTime = myNewDT.MyDateTime.Value;
para apenasthis.MyDateTime = myNewDT.MyDateTime;
A exceção que você estava recebendo foi lançada na
.Value
propriedade NullableDateTime
, pois é necessário devolver umDateTime
(já que esse é o contrato para os.Value
estados), mas não pode fazê-lo porque não háDateTime
retorno, então lança uma exceção.Em geral, é uma má idéia chamar cegamente
.Value
um tipo anulável, a menos que você tenha algum conhecimento prévio de que essa variável DEVE conter um valor (por exemplo, através de uma.HasValue
verificação).EDITAR
Aqui está o código para
DateTimeExtended
isso não gera uma exceção:Eu testei assim:
Adicionar o
.Value
onother.MyDateTime
causa uma exceção. Removê-lo se livra da exceção. Eu acho que você está procurando no lugar errado.fonte
.Value
um objeto nulo faz sentido (eu acho), mas a mensagem de exceção é realmente enganosa se você estiver lidando com dois objetos Nullable. Algo como 'A propriedade .Value exige que o objeto seja não nulo' faria muito mais sentido.Ao usar métodos de extensão LINQ (por exemplo
Select
,Where
), a função lambda pode ser convertida em SQL que pode não se comportar de forma idêntica ao seu código C #. Por exemplo, o curto-circuito do C # é avaliado&&
e||
convertido em ansiosoAND
eOR
. Isso pode causar problemas quando você está checando nulo em sua lambda.Exemplo:
fonte
Tente soltar o
.value
fonte
Nesse caso, oldDTE é nulo; portanto, quando você tenta acessar oldDTE.Value, InvalidOperationException é lançada, pois não há valor. No seu exemplo, você pode simplesmente fazer:
fonte
Atribua os membros diretamente sem a
.Value
parte:fonte
Parece que oldDTE.MyDateTime era nulo, então o construtor tentou usar o Value - que foi lançado.
fonte
Recebi esta mensagem ao tentar acessar valores de um objeto com valor nulo.
isso produzirá erro. Primeiro você deve verificar se o objeto não é nulo
Isso funciona.
fonte
this.MyDateTime = myNewDT.MyDateTime.Value;
, nãosName = myObj.Name;