Оператор с нулевым условием не работает с Func внутри универсального метода.C#

Место общения программистов C#
Anonymous
Оператор с нулевым условием не работает с Func внутри универсального метода.

Сообщение Anonymous »

Это ошибка компилятора или существует определенная выбранная причина, по которой оператор с нулевым условием не работает с Func внутри универсальных методов?

Для примера: следующее не компилируется

Код: Выделить всё

public static T Test(Func func)
{
return func?.Invoke() ?? default(T);
}
Компилятор выдает ошибку CS0023 Оператор '?' нельзя применить к операнду типа "T"

Однако я знаю, что вы можете добиться того же самого:

Код: Выделить всё

public static T Test(Func func)
{
return func != null ? func() : default(T);
}
Так почему же это запрещено?

Чтобы уточнить дальнейшее действие, однако работает так, как ожидалось.

Код: Выделить всё

public static void Test(Action action, T arg)
{
action?.Invoke(arg);
}
Обновление (17 января 2017 г.):

После некоторых дополнительных исследований это становится еще менее разумным, даже если учесть следующее:

Предположим, у нас есть класс (ссылочный тип)

Код: Выделить всё

public class Foo
{
public int Bar { get; set; }
}
и допустим, у нас есть Func

Код: Выделить всё

Func fun = () => 10;
Следующее работает:

Код: Выделить всё

// This work
var nullableBar = foo?.Bar; // type of nullableBar is int?
var bar = nullableBar ?? default(int); // type of bar is int

// And this work
nullableBar = fun?.Invoke(); // ditto
bar = nullableBar ?? default(int); // ditto
Это означает, что в соответствии с применяемой там логикой Func типа значения с использованием операторов с нулевым условием и с нулевым объединением должен работать.

Однако, как только левый универсальный тип нулевого условного оператора станет универсальным без ограничений, он не сможет применить ту же логику, которую он должен иметь возможность учитывать, он может применить одна и та же логика для обоих типов значений и ссылочных типов, когда типы применяются явно.

Я знаю об ограничениях компилятора, для меня просто не имеет смысла, почему он этого не позволяет и почему он хочет, чтобы выходные данные были разными, будь то ссылочный или значащий тип, учитывая, что применение типов вручную даст ожидаемые результаты.

Вернуться в «C#»