The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable<T>'

拈花ヽ惹草 提交于 2019-11-30 08:06:23

问题


Why am I getting this error in the following code?

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

回答1:


There are several problems with the code. The first one is that your types must be nullable. You can express that by specifying where T: struct. You will also need to specify where TResult: struct because you're using that as a nullable type too.

Once you fix up the where T: struct where TResult: struct you also need to change the return value type (which was wrong) and a number of other things too.

After fixing all those errors and simplifying, you wind up with this:

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

Note that you can rewrite Nullable<T> as T? which makes things more readable.

Also you could write that as one statement using ?: but I don't think it's as readable:

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

You might want to put this into an extension method:

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

Then you can write code like this:

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



回答2:


As the error suggests, the compiler has no guarantee that T won't already be nullable. You need to add a constraint to T:

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


来源:https://stackoverflow.com/questions/16730753/the-type-t-must-be-a-non-nullable-value-type-in-order-to-use-it-as-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!