Вызов метода MaybeNull generi c из другого метода generi c - PullRequest
3 голосов
/ 29 января 2020

У меня есть такой метод расширения:

[return: MaybeNull]
public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
where TKey : notnull
where TValue : notnull {
    if (dictionary.TryGetValue(key, out TValue value)) return value;
    else return default!;
}

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

Однако, если у меня есть другой метод, который вызывает GetValueOrDefault, и я забудьте добавить [return: MaybeNull], компилятор не предупредит меня вообще. Вот запутанный пример, чтобы объяснить мою проблему:

public static TValue SomeOtherMethod<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
where TKey : notnull
where TValue : notnull
    => dictionary.GetValueOrDefault(key); // No warning this could be null

...

var dictionary = new Dictionary<string, string>() {
    ["hello"] = "world"
};
string s1 = dictionary.GetValueOrDefault("foo"); // Compiler warning
string s2 = dictionary.SomeOtherMethod("foo"); // No compiler warning
int s2Len = s2.Length; // Visual Studio states "s2 is not null here", even though it absolutely is!

Я довольно плохо знаком с C# 8.0 обнуляемыми ссылочными типами, особенно с использованием дженериков. Я что-то пропустил, чтобы заставить это работать? Без предупреждения компилятора создается впечатление, что он отрицает цель использования C# 8.0 обнуляемых типов. Я впадаю в ложное чувство безопасности, что не могу пропустить исключение NullReferenceException, особенно когда Visual Studio заверяет меня, что «s2 здесь не равен нулю», даже если это абсолютно так.

1 Ответ

0 голосов
/ 25 апреля 2020

Это было улучшено в более новых версиях компилятора (все еще C# 8, просто более новый компилятор). Если вы используете более новую Visual Studio, вы будете иметь более новый компилятор

Вот ваш пример:.

https://sharplab.io/#v2: EYLgtghgzgLgpgJwD4GIB2BXANliwtwAEcaeBAsAFBUACADITQIwAsA3LQ8wHQAiAlhADmaAPax + AYyjcAwqIAmcAIKksATyj8oHapRoBmRkwBsjAEyFZhAN5VCDxkeZmaLQgFkAFAEpb9xwBfAIcQwgBtGgB2EE8IdWA4ADlsLABdMMNjMwAVADUILAwiAHE4GAKiuAB5BF44ADMIbBgAHhyAaTh1ABpCfMLigD4vGAALbUIASQFJGH5RUgR1dq7e / srhwgUpecWIZb7O7sIAa26fMMdCAHcxxCJj9UJYsRhMHCvHO4eNwaJXqJ3qkwnZKNdrvwGoQvDs5gslupuDllmUKv8vOd1qIMDA / lVCAA3f4 + S7giEU6JE / 66CkOOBYKBwL6UqLbRrNLAwWlBMKZZymfHFQgAZVEYBq40QHnKY0Uq26R02cBG40mM12CIOKyeSv + Q22mv2h36azOFxZt3uCEeZsBwM + 5IpPxtQoBhDeHywYQAvAa4XtEdw0cravUmi1MRc2IQAPSxwhJUS3A5ofhoISENVQQiSHFYBSERIekGUQJAA ===

1009 * Есть два улучшения:
  1. Вам не нужно ! The default как анализ в настоящее время уважает MaybeNull атрибут GetValueOrDefault.
  2. Теперь вы получаете предупреждение CS8603 (возможен возврат нулевой ссылки), где вы ранее указывали, что не получили предупреждение, но справедливо должен.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...