Je suis nouveau sur C # et je ne comprends pas pourquoi le code suivant ne fonctionne pas.
public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : IComparable
{
if (a.HasValue && b.HasValue)
return a.Value.CompareTo(b.Value) < 0 ? b : a;
else if (a.HasValue)
return a;
else
return b;
}
// Sample usage:
public DateTime? CalculateDate(DataRow row)
{
DateTime? result = null;
if (!(row["EXPIRATION_DATE"] is DBNull))
result = DateTime.Parse((string)row["EXPIRATION_DATE"]);
if (!(row["SHIPPING_DATE"] is DBNull))
result = CoalesceMax(
result
DateTime.Parse((string)row["SHIPPING_DATE"]).AddYears(1));
// etc.
return result;
}
Il donne l'erreur suivante lors de la compilation:
Le type 'T' doit être un type de valeur non nullable afin de l'utiliser comme paramètre 'T' dans le type ou la méthode générique 'System.Nullable <T>'
Vous devez ajouter une contrainte T: struct:
public static Nullable<T> CoalesceMax<T>
(Nullable<T> a, Nullable<T> b) where T : struct, IComparable
Sinon, C # essaiera de déterminer ce que Nullable<T>
signifie, et réalisez qu'il n'a pas déjà la contrainte requise par Nullable<T>
lui-même. En d'autres termes, vous pouvez essayer d'appeler:
CoalesceMax<string>(...)
ce qui n'aurait pas de sens, comme Nullable<string>
n'est pas valide.
Le Nullable<T>
type a une contrainte qui requiert que T
soit un type valeur (struct
en C #). C'est pourquoi le compilateur vous parle de Nullable<T>
et non votre fonction ou le site d'appel de cette fonction - c'est la classe Nullable
qui est la cause principale de l'erreur, donc c'est en fait plus utile que si le compilateur pointait simplement vers votre fonction et disait "ce n'est pas bien, corrige ça!" (Imaginez si CoalesceMax
utilisait plusieurs génériques et violait la contrainte sur un seul d'entre eux - il est plus utile de savoir quel générique avait sa contrainte cassée que de savoir qu'une ou plusieurs contraintes dans CoalesceMax
étaient cassés).
La solution est de rendre votre T
et leur T
compatibles en introduisant la même contrainte. Cela se fait en ajoutant la contrainte struct
, qui doit précéder toutes les contraintes d'interface/nouvelles:
public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : struct, IComparable{
...
}
Votre méthode générique utilise un Nullable<T>
.
Cependant, vous ne contraignez pas le type de T
, il pourrait donc finir par être Nullable<Form>
, ce qui n'est évidemment pas valide.
Vous devez remplacer la contrainte par where T : struct, IComparable
pour garantir que T
ne peut être qu'un type de valeur.
Pas exactement une réponse à l'OP mais comme c'était la première chose qui apparaissait sur google pour le même message d'erreur, j'ai dû ajouter la contrainte sur ma définition de classe, plutôt que sur ma méthode, par exemple
public class MyClass<T> where T : struct
{
public void MyMethod(T? value)
{
}
}