В исходной реализации foo
было бы выведено как Foo
.
Однако люди жаловались, что это мешает таким вещам, как:
string? GetThing() => ...
var result = "";
if (condition)
{
result = GetThing();
}
Если result
выводится как string
, тогда строка result = GetThing()
вызывает предупреждение: GetThing()
возвращает string?
, и появляется предупреждение, если вы пытаетесь присвоить string?
string
.
Решение заключалось в том, чтобы вывести result
как string?
, но компилятор знает, что в настоящее время он не равен нулю (его «состояние потока» - «NotNull»).
Это означает, что :
string? GetThing() => ...
var result = "";
// No warning, as the compiler knows that result isn't null
int l1 = result.Length;
if (condition)
{
result = GetThing();
}
// Warning: the compiler knows 'result' might have been re-assigned
int l2 = result.Length;
Для других примеров состояния потока в работе см. Такие вещи, как:
string? result = GetString();
if (result == null)
throw new Exception();
// No warning: the compiler knows that result can't be null here: if it was,
// the exception above would have been thrown
int l1 = result.Length;
string? result = GetString();
// Warning: result might be null
int l1 = result.Length;
// No warning: the compiler knows that result can't be null here: if it was,
// the line above would have thrown
int l2 = result.Length;
string result = "hello";
if (result == null)
Console.WriteLine("NULL!");
// Warning: because we checked for null above, the compiler assumes that we
// know something that it doesn't, and so result might be null.
int l1 = result.Length;