Для меня это выглядит прекрасно, передать нулевой параметр в качестве Task.FromResult
.
Нет, это плохая идея.
Если caller указывает ненулевой тип для T
, тогда default(T)
можно считать «неопределенным» (на самом деле это null
, но это главный недостаток реализации C# 8.0 не-обнуляемых ссылочных типов ( т. е. они могут все еще быть null
, grrrr.) Рассмотрим:
// Compiled with C# 8.0's non-nullable reference-types enabled.
Task<String> task = GetDefaultTask<String>();
String result = await task;
Console.WriteLine( result.Length ); // <-- NullReferenceException at runtime even though the C# compiler reported `result` cannot be null.
Избегайте использования default
/ default(T)
в C# 8.0 для типов generi c без адекватные ограничения типов.
Существует несколько решений этой проблемы:
1: укажите значение по умолчанию, предоставляемое вызывающим абонентом:
public Task<T> GetDefaultTask<T>( T defaultValue )
{
return Task.FromResult( defaultValue );
}
Так что вызов сайт должен быть обновлен, и компилятор C# выдаст предупреждение или ошибку, если вызывающая сторона попытается использовать null
вместо исключения во время выполнения:
Task<String> task = GetDefaultTask<String>( defaultValue: null ); // <-- compiler error or warning because `null` cannot be used here.
String result = await task;
Console.WriteLine( result.Length );
2: Добавить структуру против ограничений класса в различных методах:
default(T)
типа struct
/ value может быть значимым (или может быть столь же опасным, как null
...), поскольку мы можем безопасно использовать default(T)
, где T : struct
, но не default(T)
, где T : class
, мы можем добавить различные перегрузки для этого случая:
public Task<T> GetDefaultTask<T>()
where T : struct
{
return Task.FromResult( default(T) );
}
public Task<T> GetDefaultTask<T>( T defaultValue )
where T : class
{
return Task.FromResult( defaultValue );
}
( Обратите внимание, что вы не можете перегружать методы, основанные исключительно на обобщенных типовых ограничениях c - вы можете перегружать только обобщенные c счетчики параметров и обычные типы параметров.