类型’T’必须是非可空值类型,以便在generics类型或方法’System.Nullable ‘中将其用作参数’T’

为什么我在以下代码中收到此错误?

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