Тип «T» должен быть невообразимым типом значения, чтобы использовать его как параметр «T» в родовом типе или методе «System.Nullable »

Почему я получаю эту ошибку в следующем коде?

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(); } } 

Существует несколько проблем с кодом. Первый заключается в том, что ваши типы должны быть обнуляемыми. Вы можете выразить это, указав, where T: struct . Вам также необходимо указать, where TResult: struct потому что вы используете это как нулевой тип тоже.

Как только вы исправите where T: struct where TResult: struct вам также необходимо изменить тип возвращаемого значения (что было неправильно) и ряд других вещей.

После исправления всех этих ошибок и упрощения вы завершаете это:

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

Обратите внимание, что вы можете переписать Nullable как T? что делает вещи более читаемыми.

Также вы можете написать это как одно заявление, используя ?: Но я не думаю, что это так же читаемо:

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

Возможно, вы захотите включить это в метод расширения:

 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; } } 

Затем вы можете написать код следующим образом:

 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); 

Как показывает ошибка, компилятор не гарантирует, что T уже не может быть нулевым. Вам нужно добавить ограничение на T:

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