14

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

void Main()
{
    int? a = 1;
    int? b = AddOne(1);
    a.Dump();
}

static Nullable<int> AddOne(Nullable<int> nullable)
{
    return ApplyFunction<int, int>(nullable, (int x) => x + 1);
}

static Nullable<T> ApplyFunction<T, TResult>(Nullable<T> nullable, Func<T, TResult> function)
{
    if (nullable.HasValue)
    {
        T unwrapped = nullable.Value;
        TResult result = function(unwrapped);
        return new Nullable<TResult>(result);
    }
    else
    {
        return new Nullable<T>();
    }
}
4

2 回答 2

19

代码有几个问题。第一个是您的类型必须可以为空。您可以通过指定where T: struct. 您还需要指定where TResult: struct,因为您也将其用作可为空的类型。

一旦你修复了,where T: struct where TResult: struct你还需要更改返回值类型(这是错误的)以及其他一些事情。

在修复所有这些错误并简化之后,您将得到以下结果:

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

请注意,您可以重写Nullable<T>T?这使事情更具可读性。

您也可以使用以下语句将其写为一个语句,?:但我认为它不具有可读性:

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

您可能希望将其放入扩展方法中:

public static class NullableExt
{
    public static TResult? ApplyFunction<T, TResult>(this T? nullable, Func<T, TResult> 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);
于 2013-05-24T08:42:14.770 回答
6

正如错误所暗示的那样,编译器不能保证 T 不会已经可以为空。您需要向 T 添加一个约束:

static Nullable<T> ApplyFunction<T, TResult>(Nullable<T> nullable, 
    Func<T, TResult> function) : where T : struct 
                                 where TResult : struct
于 2013-05-24T08:37:57.740 回答