O tipo ‘T’ deve ser um tipo de valor não anulável para usá-lo como parâmetro ‘T’ no tipo genérico ou método ‘System.Nullable ‘

Por que estou recebendo esse erro no código a seguir?

void Main() { int? a = 1; int? b = AddOne(1); a.Dump(); } static Nullable AddOne(Nullable nullable) { return ApplyFunction(nullable, (int x) => x + 1); } static Nullable ApplyFunction(Nullable nullable, Func function) { if (nullable.HasValue) { T unwrapped = nullable.Value; TResult result = function(unwrapped); return new Nullable(result); } else { return new Nullable(); } } 

Existem vários problemas com o código. A primeira é que seus tipos devem ser anuláveis. Você pode expressar isso especificando where T: struct . Você também precisará especificar where TResult: struct porque você está usando isso como um tipo anulável também.

Depois de consertar o where T: struct where TResult: struct você também precisa alterar o tipo de valor de retorno (que estava errado) e uma série de outras coisas também.

Depois de consertar todos esses erros e simplificar, você acaba com isso:

 static TResult? ApplyFunction(T? nullable, Func function) where T: struct where TResult: struct { if (nullable.HasValue) return function(nullable.Value); else return null; } 

Note que você pode rewrite Nullable como T? o que torna as coisas mais legíveis.

Também você poderia escrever isso como uma declaração usando ?: Mas eu não acho que seja tão legível:

 return nullable.HasValue ? (TResult?) function(nullable.Value) : null; 

Você pode querer colocar isso em um método de extensão:

 public static class NullableExt { public static TResult? ApplyFunction(this T? nullable, Func function) where T: struct where TResult: struct { if (nullable.HasValue) return function(nullable.Value); else return null; } } 

Então você pode escrever código como este:

 int? x = 10; double? x1 = x.ApplyFunction(i => Math.Sqrt(i)); Console.WriteLine(x1); int? y = null; double? y1 = y.ApplyFunction(i => Math.Sqrt(i)); Console.WriteLine(y1); 

Como o erro sugere, o compilador não tem garantia de que o T não será anulável. Você precisa adicionar uma restrição a T:

 static Nullable ApplyFunction(Nullable nullable, Func function) : where T : struct where TResult : struct