Возможно ли, чтобы метод asyn c когда-либо возвращал null в C#? - PullRequest
2 голосов
/ 29 мая 2020

Копаясь в каком-то старом коде, я заметил вызов метода async, а затем проверку задачи, возвращаемой для null .

async Task<Something> DoSomeStuffAsync()
{
    //...
    return null; //not the actual return, but I guess it doesn't matter
}


var result = DoSomeStuffAsync(); //without await
if(result == null)
{
    //does this part makes any sense
}

Насколько я понимаю ключевого слова async, этот сценарий никогда не будет возможен, потому что результат метода async всегда будет заключен в Task, но просто для проверки, я что-то упускаю?

Есть ли какие-либо случай, когда метод async вернет null in C#?

Ответы [ 3 ]

2 голосов
/ 29 мая 2020

Согласно статье MSDN asyn c методы могут иметь следующие типы возвращаемых значений:

  • Task, для asyn c метода, который возвращает значение.

  • Task для асинхронного c метода, который выполняет операцию, но не возвращает значения. void для обработчика событий.

  • Начиная с C# 7.0, любой тип, имеющий доступный метод GetAwaiter. Объект, возвращаемый методом GetAwaiter, должен реализовывать интерфейс System.Runtime.CompilerServices.ICriticalNotifyCompletion.

  • Начиная с C# 8.0, IAsyncEnumerable для метода asyn c, который возвращает asyn c stream.

Итак, Task представляет выполнение асинхронного метода и никогда не должно быть null, , потому что Task представляет текущий процесс для вызывающего с обязательство произвести фактическую стоимость после завершения работы.

2 голосов
/ 29 мая 2020

Метод с пометкой async не может вернуть null.

Однако для вызывающего , метод не async или нет, он просто возвращает ожидаемый (Task ... или другие ожидаемые типы, которые не входят в объем вопроса), поэтому действительно возможно, что он вернет null.

Т.е. вызывающий не может различать guish между:

async Task Foo()
//...

и:

Task Foo()
//...

И последний метод может отлично вернуть null

Таким образом, нулевая проверка вполне допустима для вызывающего

0 голосов
/ 29 мая 2020

Хотя верно, что DoSomeStuffAsync() когда-нибудь может быть изменен на метод, отличный от async, совершенно ясно, что он предназначен для async, и вы, вероятно, нашли ошибку. Звонка, вероятно, следовало дождаться. Если вызов не предназначался для ожидания (например, result действительно должен был быть Task), тогда проверка на null бессмысленна, и, вероятно, должен быть комментарий, объясняющий, почему вызов не ожидался.

Тестирование потенциальных будущих изменений API, например, возможность для DoSomeStuffAsync() возвращать null, не относится к производственному коду. Недоверие к контрактам и документации API («Asyn c» в имени метода - это форма документации) и засорение кода бессмысленными нулевыми проверками - характерные черты c неопытных программистов.

...