Il y a un paradoxe dans la description de l'exception: l'objet Nullable doit avoir une valeur (?!)
C'est le problème:
J'ai une classe DateTimeExtended
qui a
{
DateTime? MyDataTime;
int? otherdata;
}
et un constructeur
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime.Value;
this.otherdata = myNewDT.otherdata;
}
exécuter ce code
DateTimeExtended res = new DateTimeExtended(oldDTE);
jette un InvalidOperationException
avec le message:
L'objet nullable doit avoir une valeur.
myNewDT.MyDateTime.Value
- est valide et contient un objet DateTime
normal.
Quel est le sens de ce message et que fais-je de travers?
Notez que oldDTE
n'est pas null
. J'ai supprimé la Value
de myNewDT.MyDateTime
, mais la même exception est levée en raison d'un setter généré.
Vous devez modifier la ligne _this.MyDateTime = myNewDT.MyDateTime.Value;
_ en _this.MyDateTime = myNewDT.MyDateTime;
_
L'exception que vous receviez a été levée dans la propriété .Value
de NullableDateTime
, car il est nécessaire de renvoyer un DateTime
(puisque c'est ce que stipule le contrat pour _.Value
_), mais il ne peut pas le faire car il n'y a pas de variable DateTime
à renvoyer, elle génère donc une exception.
En général, c’est une mauvaise idée d’appeler aveuglément _.Value
_ sur un type nullable, sauf si vous savez au préalable que cette variable DOIT contient une valeur (c'est-à-dire par le biais d'un .HasValue
cocher).
EDIT
Voici le code pour DateTimeExtended
qui ne lève pas d'exception:
_class DateTimeExtended
{
public DateTime? MyDateTime;
public int? otherdata;
public DateTimeExtended() { }
public DateTimeExtended(DateTimeExtended other)
{
this.MyDateTime = other.MyDateTime;
this.otherdata = other.otherdata;
}
}
_
Je l'ai testé comme ça:
_DateTimeExtended dt1 = new DateTimeExtended();
DateTimeExtended dt2 = new DateTimeExtended(dt1);
_
L'ajout de _.Value
_ sur _other.MyDateTime
_ provoque une exception. Le supprimer supprime l'exception. Je pense que vous cherchez au mauvais endroit.
Lorsque vous utilisez des méthodes d'extension LINQ (par exemple, Select
, Where
), la fonction lambda peut être convertie en SQL sans que son comportement ne soit pas identique à celui de votre code C #. Par exemple, le court-circuit évalué par C # ||
et &&
est converti en SQL désireux AND
et OR
. Cela peut entraîner des problèmes lorsque vous recherchez la valeur null dans votre lambda.
Exemple:
MyEnum? type = null;
Entities.Table.Where(a => type == null ||
a.type == (int)type).ToArray(); // Exception: Nullable object must have a value
Essayez de laisser tomber le .value
_DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime;
this.otherdata = myNewDT.otherdata;
}
_
Dans ce cas oldDTE a la valeur null. Ainsi, lorsque vous essayez d'accéder à oldDTE.Value, l'exception InvalidOperationException est levée car il n'y a pas de valeur. Dans votre exemple, vous pouvez simplement faire:
this.MyDateTime = newDT.MyDateTime;
Affectez les membres directement sans la partie .Value
:
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime;
this.otherdata = myNewDT.otherdata;
}
On dirait que oldDTE.MyDateTime était null, le constructeur a donc essayé de prendre sa valeur - qui l'a renvoyée.
J'ai reçu ce message en essayant d'accéder aux valeurs d'un objet à valeur nulle.
sName = myObj.Name;
cela produira une erreur. D'abord, vous devriez vérifier si l'objet n'est pas null
if(myObj != null)
sName = myObj.Name;
Cela marche.