Opérateur ‘??’ ne peut pas être appliqué aux opérandes de type ‘T’ et ‘T’

J’ai la méthode générique suivante, mais VS me donne une erreur de compilation à ce sujet. (Opérateur ‘??’ ne peut pas être appliqué aux opérandes de type ‘T’ et ‘T’)

public static T Method(T model) where T : new() { var m = model ?? new T(); } 

Est-ce que quelqu’un a une idée pourquoi?

Edit: Est-ce possible parce que T peut être une structure dans mon cas, et une structure est un type non nullable?

Vous devez append class contrainte de class :

 public static T Method(T model) where T : class, new() { var m = model ?? new T(); return m; } 

Et vous devriez retourner m aussi!

Note: Comme @KristofDegrave mentionné dans son commentaire, la raison pour laquelle nous devons append class contrainte de class est que T peut être un type de valeur, comme int et depuis ?? operator (null-coalescing) vérifie les types pouvant être null, nous devons donc append class contrainte de class pour exclure les types de valeur.

Edit: La réponse d’Alvin Wong couvrait également le cas des types nullables; qui sont des structures en fait, mais peuvent être des opérandes de ?? opérateur. Sachez simplement que Method renverrait null sans la version surchargée d’Alvin, pour les types nullables.

?? est l’opérateur de coalescence nulle. Il ne peut pas être appliqué aux types non nullables. Puisque T peut être n’importe quoi, il peut s’agir d’un int ou d’un autre type primitif, non nullable.

Si vous ajoutez la condition where T : class (doit être spécifié avant new() ), cela oblige T à être une instance de classe, ce qui est nullable.

Beaucoup ont déjà souligné que l’ajout de la contrainte de class pour le générique résoudra le problème.

Si vous souhaitez que votre méthode soit également applicable à Nullable , vous pouvez y append une surcharge:

 // For reference types public static T Method(T model) where T : class, new() { return model ?? new T(); } // For Nullable public static T Method(T? model) where T : struct { return model ?? new T(); // OR return model ?? default(T); } 

Vous devez spécifier que votre type T est une classe avec une contrainte sur le type générique:

 public static T Method(T model) where T : class, new() { return model ?? new T(); } 

Puisque T peut être n’importe quel type, il n’y a aucune garantie que T aura un statique ?? opérateur ou que le type T est nullable.

?? Opérateur (Référence C #)

Le ?? L’opérateur est appelé opérateur de coalescence null et permet de définir une valeur par défaut pour les types de valeur ou les types de référence nullables .

Pour une raison quelconque le ?? L’opérateur ne peut pas être utilisé sur des types non nullables, même s’il est supposé être équivalent à model == null ? new T() : model model == null ? new T() : model , et vous êtes autorisé à effectuer une comparaison nulle avec un type non nullable.

Vous pouvez obtenir exactement ce que vous recherchez sans aucune contrainte supplémentaire en utilisant plutôt l’opérateur ternary ou une instruction if:

 public static T Method(T model) where T : new() { var m = model == null ? new T() : model; } 

model ?? new T() model ?? new T() signifie model == null ? new T() : model model == null ? new T() : model . Il n’est pas garanti que le modèle ne soit pas nullable et que == ne puisse pas être appliqué pour un object null et un object non nullable. Changer la contrainte à l’ where T : class, new() devrait fonctionner.

Mark T comme “classe” et vous êtes prêt à partir.