Тип 'T' должен быть необнуляемым типом значения, чтобы использовать его в качестве параметра 'T' в универсальном типе или методе '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();
    }
}
 David Heffernan24 мая 2013 г., 10:41
Почему отрицательные голоса? Похоже, здоровый вопрос для меня.
 John Willemse24 мая 2013 г., 10:39
Можно'проверить это прямо сейчас, но вы звонитеApplyFunction вместо ?ApplyFunction
 John Willemse24 мая 2013 г., 10:35
И в чем вопрос ??

Ответы на вопрос(2)

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

static Nullable ApplyFunction(Nullable nullable, 
    Func function) : where T : struct 
                                 where TResult : struct
 Matthew Watson24 мая 2013 г., 10:44
Вы'понадобится больше изменений, чтобы это заработало. Например, TResult тоже должен быть структурой.
 T. Kiley24 мая 2013 г., 10:56
Правда, пропустилTResult? фиксированный :)
Решение Вопроса

Есть несколько проблем с кодом. Во-первых, ваши типы должны быть обнуляемыми. Вы можете выразить это, указав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);
 Steve Temple24 мая 2013 г., 12:29
Извините, что неправильно прочиталправильно, если вы хотите вызвать функцию, которая выигралат работа
 Shawn Kovac02 мар. 2015 г., 18:29
Вы заявляете, чтоreturn nullable.HasValue ? (TResult?) function(nullable.Value) : null; ISN»так читаемо (что я согласен), но если вы добавите параметр к этому методу расширения:, TResult resultWhenNull = default(TResult) тогда вы можете сделать тело метода более читабельнымreturn (nullable.HasValue) ? function(nullable.Value) : resultWhenNull;, Кроме того, он добавляет функцию: вы можете указать значение по умолчанию, когда ваш nullable равен нулю, но это 'Это только необязательный параметр, поэтомуЭто не неудобство, которое всегда нужно пропустить. ;)
 Jeppe Stig Nielsen24 мая 2013 г., 10:56
Вместо того чтобы писатьnew TResult?()нетТочнее просто написатьnull? Тот'с философиейNullable, Похоже.
 Shawn Kovac03 мар. 2015 г., 22:51
так что я думаю, что тело этого метода теперь более читабельно, чем если быif заявление были использованы. ;) спасибо за это исправление, Мэтью! Я очень ценю это!
 Shawn Kovac03 мар. 2015 г., 22:49
поэтому мой полный метод:public static TResult? ApplyFunc(this T? nullable, Func function, TResult? resultWhenNull = null) where T : struct where TResult : struct { return (nullable.HasValue) ? function(nullable.Value) : resultWhenNull; }
 Shawn Kovac03 мар. 2015 г., 22:55
я просто хочу показать, насколько хорош C # для нас, чтобы простить пропущенные новые строки, где мой код запускается вместе в одной строке, из-за ограничения комментариев на этом форуме. Я говорю 'уф! что это не вопрос VB! ;)
 Matthew Watson24 мая 2013 г., 10:59
@JeppeStigNielsen Это точно так и есть. Я'обновлю. :)
 Shawn Kovac03 мар. 2015 г., 22:47
@ MatthewWatson спасибо, я закодировал это так, как выразился в моем методе, но, как вы правильно заметили, это 'не то, что я действительно хотел. теперь я исправил свой код, поэтому новый параметр, TResult? resultWhenNull = null, Спасибо!!
 Steve Temple24 мая 2013 г., 12:04
Вместо: вернуть nullable.HasValue? (TResult?) Function (nullable.Value): null; вы могли бы сделать возврат nullable ?? null; что немного приятнее и читабельнее
 Matthew Watson24 мая 2013 г., 12:19
@SteveTemple Как тогда делаетfunction() позвонить?
 Matthew Watson04 мар. 2015 г., 08:22
@ShawnKovac Да, это 'хорошее дополнение. :)
 Matthew Watson03 мар. 2015 г., 10:36
@ShawnKovac Ваш предложенныйresultWhenNull имеет типTResult который необнуляемый тип, что означает, что вы не можетеt вернуть нуль из метода. Вы хотели сделать это шрифтом?TResult?

Ваш ответ на вопрос