Непонятно об ошибке компилятора при использовании «out» в блоке async-await в C # - PullRequest
0 голосов
/ 26 апреля 2018

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

async void Foo() {
  bool success;

  // stuff

  await Task.Run(
    () => Bar(out success)
  );

  if (!success) { // this is the line causing the compiler-error
    // handle
  }

  // other stuff
}

void Bar(out bool success);

Но я получаю ошибку

CS0165 Использование неназначенноголокальная переменная 'success'

Это не так уж сложно, так как я могу получить симпатичную инициализацию success=false и передать ее как ref вместо out, и это, похоже, работает какжелательно.Тем не менее, мне любопытно, какие тонкости async-await (или Task.Run), кажется, приводят к случаю, который не гарантирует, что out success будет правильно назначен.

Любое просветлениеприветствуется!

Редактировать:

Чтобы добавить немного контекста, следующий блок компилируется и выполняется нормально.

void Caller() {
  bool success;
  Callee(out success);
  if (success) {
    // do something
  }
}

void Callee();

Это потому, что out параметры не требуется инициализировать перед передачей.Подробнее о out: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-parameter-modifier

1 Ответ

0 голосов
/ 26 апреля 2018

Рассмотрим следующую возможную (хотя и совершенно неверную) реализацию Task.Run:

public class Task
{
    public static Task Run(Action action)
    {
        return Task.Delay(500);
    }
    //...
}

Теперь подумайте о рассматриваемом коде.С этой реализацией Task.Run будет ли когда-нибудь вызываться метод Bar?Нет. Поэтому success никогда не будет инициализирован, и сделана попытка доступа к неинициализированной переменной.

Компилятор не имеет представления о реальной реализации Task.Run или о том, что он будет делать.Он не может предполагать, что он не реализован так, как у меня выше, и поэтому возможна неинициализированная переменная.

...