Hay una paradoja en la descripción de la excepción: el objeto anulable debe tener un valor (?!)
Este es el problema:
Tengo una DateTimeExtended
clase que tiene
{
DateTime? MyDataTime;
int? otherdata;
}
y un constructor
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime.Value;
this.otherdata = myNewDT.otherdata;
}
ejecutando este código
DateTimeExtended res = new DateTimeExtended(oldDTE);
arroja un InvalidOperationException
con el mensaje:
Objeto nullable debe tener un valor.
myNewDT.MyDateTime.Value
- es válido y contiene un DateTime
objeto regular .
¿Cuál es el significado de este mensaje y qué estoy haciendo mal?
Tenga en cuenta que oldDTE
no lo es null
. He quitado el Value
de myNewDT.MyDateTime
pero la misma excepción se produce debido a un colocador generado.
Respuestas:
Deberías cambiar la línea
this.MyDateTime = myNewDT.MyDateTime.Value;
a solothis.MyDateTime = myNewDT.MyDateTime;
La excepción que estaba recibiendo fue lanzada en la
.Value
propiedad de NullableDateTime
, ya que se requiere que devuelva unDateTime
(ya que ese es el contrato para los.Value
estados), pero no puede hacerlo porque no hayDateTime
devolución, por lo que arroja una excepción.En general, es una mala idea llamar ciegamente
.Value
a un tipo anulable, a menos que tenga algún conocimiento previo de que esa variable DEBE contener un valor (es decir, a través de una.HasValue
verificación).EDITAR
Aquí está el código para
DateTimeExtended
eso no arroja una excepción:Lo probé así:
Agregar el
.Value
encendidoother.MyDateTime
provoca una excepción. Eliminarlo elimina la excepción. Creo que estás buscando en el lugar equivocado.fuente
.Value
a un objeto nulo tiene sentido (supongo), pero el mensaje de excepción es realmente engañoso si se trata de dos objetos Nullable. Algo como 'La propiedad .Value requiere que el objeto sea no nulo' tendría mucho más sentido.Cuando se utilizan métodos de extensión LINQ (por ejemplo
Select
,Where
), la función lambda puede convertirse a SQL que puede no comportarse de manera idéntica a su código C #. Por ejemplo, el cortocircuito de C # se evalúa&&
y||
se convierte en el ansiosoAND
y de SQLOR
. Esto puede causar problemas cuando está buscando nulos en su lambda.Ejemplo:
fuente
Intenta soltar el
.value
fuente
En este caso, oldDTE es nulo, por lo tanto, cuando intente acceder a oldDTE.Value, se arroja InvalidOperationException ya que no hay ningún valor. En su ejemplo, simplemente puede hacer:
fuente
Asigne los miembros directamente sin la
.Value
parte:fuente
Parece que oldDTE.MyDateTime era nulo, por lo que el constructor intentó tomar su valor, lo que arrojó.
fuente
Recibí este mensaje al intentar acceder a los valores de un objeto con valor nulo.
Esto producirá un error. Primero debe verificar si el objeto no es nulo
Esto funciona.
fuente
this.MyDateTime = myNewDT.MyDateTime.Value;
, nosName = myObj.Name;
Tengo esta solución y está funcionando para mí.
fuente