c# - validar - Objeto nullable debe tener un valor
nullable property c# (7)
Hay una paradoja en la descripción de la excepción: el objeto anulable debe tener un valor (?!)
Este es el problema:
Tengo una clase DateTimeExtended
, que tiene
{
DateTime? MyDataTime;
int? otherdata;
}
y un constructor
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime.Value;
this.otherdata = myNewDT.otherdata;
}
corriendo este código
DateTimeExtended res = new DateTimeExtended(oldDTE);
arroja una InvalidOperationException
con el mensaje:
Objeto nullable debe tener un valor.
myNewDT.MyDateTime.Value
- es válido y contiene un objeto DateTime
regular.
¿Cuál es el significado de este mensaje y qué estoy haciendo mal?
Tenga en cuenta que oldDTE
no es null
. He eliminado el Value
de myNewDT.MyDateTime
pero se myNewDT.MyDateTime
la misma excepción debido a un setter generado.
Al usar métodos de extensión LINQ (por ejemplo, Select
, Where
), la función lambda podría convertirse a SQL que podría no comportarse de manera idéntica a su código C #. Por ejemplo, se evaluó el cortocircuito de C # ||
y &&
se convierten a ansiosos AND
y OR
SQL. Esto puede causar problemas cuando está buscando nulo en su lambda.
Ejemplo:
MyEnum? type = null;
Entities.Table.Where(a => type == null ||
a.type == (int)type).ToArray(); // Exception: Nullable object must have a value
Asigne los miembros directamente sin la parte .Value
:
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime;
this.otherdata = myNewDT.otherdata;
}
Debe cambiar la línea this.MyDateTime = myNewDT.MyDateTime.Value;
simplemente this.MyDateTime = myNewDT.MyDateTime;
La excepción que recibía se .Value
en la propiedad .Value del DateTime
Nullable , ya que se requiere devolver un DateTime
(ya que eso es lo que establece el contrato para .Value
), pero no puede hacerlo porque no hay DateTime
para devolver. , por lo que arroja una excepción.
En general, es una mala idea llamar ciegamente a .Value
en 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 comprobación .HasValue
).
EDITAR
Aquí está el código para DateTimeExtended
que no lanza una excepción:
class DateTimeExtended
{
public DateTime? MyDateTime;
public int? otherdata;
public DateTimeExtended() { }
public DateTimeExtended(DateTimeExtended other)
{
this.MyDateTime = other.MyDateTime;
this.otherdata = other.otherdata;
}
}
Lo probé así:
DateTimeExtended dt1 = new DateTimeExtended();
DateTimeExtended dt2 = new DateTimeExtended(dt1);
Agregar .Value
en other.MyDateTime
causa una excepción. Quitarlo elimina la excepción. Creo que estás buscando en el lugar equivocado.
En este caso, oldDTE es nulo, por lo tanto, cuando intenta acceder a oldDTE.Value, se lanza InvalidOperationException ya que no hay ningún valor. En su ejemplo, simplemente puede hacer:
this.MyDateTime = newDT.MyDateTime;
Parece que oldDTE.MyDateTime era nulo, por lo que el constructor intentó tomar su valor, que arrojó.
Prueba a soltar el valor.
Recibí este mensaje cuando trato de acceder a los valores de un objeto con valor nulo.
sName = myObj.Name;
esto producirá error. Primero debes verificar si el objeto no es nulo
if(myObj != null)
sName = myObj.Name;
Esto funciona.