Opérateur ‘?’ ne peut pas être appliqué à l’opérande de type ‘T’

Essayer de rendre Feature générique puis soudain le compilateur dit

Opérateur ‘?’ ne peut pas être appliqué à l’opérande de type ‘T’

Voici le code

 public abstract class Feature { public T Value { get { return GetValue?.Invoke(); } // here is error set { SetValue?.Invoke(value); } } public Func GetValue { get; set; } public Action SetValue { get; set; } } 

Il est possible d’utiliser ce code à la place

 get { if (GetValue != null) return GetValue(); return default(T); } 

Mais je me demande comment réparer ce joli one-line C # 6.0.

    Puisque tout ne peut pas être null , vous devez restreindre T pour que quelque chose soit null (un object ). Les structures ne peuvent pas être nulles, et les enums non plus.

    L’ajout d’une class Where à résoudre le problème:

     public abstract class Feature where T : class 

    Alors, pourquoi ça ne marche pas?

    Invoke() donne T Si GetValue est null , le ? L’opérateur définit la valeur de retour du type T sur null , ce qu’il ne peut pas. Si T est int par exemple, il ne peut pas la rendre nulle ( int? ) Car le type requirejs ( T = int ) ne l’est pas.

    Si vous changez T pour être int dans votre code, vous verrez le problème très clairement. Le résultat final de ce que vous demandez est ceci:

     get { int? x = GetValue?.Invoke(); return x.GetValueOrDefault(0); } 

    Ce n’est pas quelque chose que l’opérateur de propagation nulle fera pour vous. Si vous revenez à l’utilisation de default(T) il sait exactement quoi faire et vous évitez la propagation de “problèmes” de null.

    T doit être un type de référence ou un type nullable

     public abstract class Feature where T : class { // ... } 

    Pour autant que je sache le ?. L’opérateur est codé en dur pour fonctionner avec null , c’est-à-dire qu’il fonctionne pour les types de référence ou les types de valeur nullable, mais pas les types de valeur normaux . Le problème est probablement que l’opérateur retourne la valeur null si l’expression était null au lieu de la default(T) .

    Vous pourrez peut-être résoudre ce problème en limitant T à la class ici.