← Барлық мақалаларға оралу

[NotNullWhen(true)] арқылы Nullable Annotations оңтайландыру

Жарияланды

Егер C# ішінде nullable annotations enable еткен болсаңыз, CS8602 және CS8603 warnings көрген шығарсыз.

Бұл warnings-тің кейбірі possible null-reference errors табуға пайдалы. Бірақ complex methods ішінде compiler custom checks-ті әрқашан түсіне бермейді. Сіз already checked жасасаңыз да, ол values null болуы мүмкін деп ойлайды.

System.Diagnostics.CodeAnalysis ішіндегі attributes method contracts explicit сипаттауға және осы noise алып тастауға мүмкіндік береді.

Simple Try* Example

Before: Noisy Warnings

bool TryGetDomain(string? url, out string? domain)
{
    if (url is null || !url.Contains("://"))
    {
        domain = null;
        return false;
    }

    domain = url.Split("://")[1];
    return true; // domain is not null here
}

if (TryGetDomain(link, out var d))
{
    Console.WriteLine(d.Length); // CS8602: Possible null reference
}

Compiler domain nullable declared екенін көреді және method true return етсе де, ол null болуы мүмкін деп assumes етеді.

After: Explicit Contract, No Noise

using System.Diagnostics.CodeAnalysis;

bool TryGetDomain(
    string? url,
    [NotNullWhen(true)] out string? domain)
{
    if (url is null || !url.Contains("://"))
    {
        domain = null;
        return false; // null is allowed when we return false
    }

    domain = url.Split("://")[1];
    return true; // null is impossible when we return true
}

if (TryGetDomain(link, out var d))
{
    Console.WriteLine(d.Length); // No warning
}

[NotNullWhen(true)] analyzer-ге: “Method true return етсе, out parameter never null” деп айтады.

Result - fewer manual checks бар cleaner call sites.

Неге керек?

  1. Null checks азаяды. Code leaner қалады.

  2. Signature ішіндегі contracts. Reading және code review кезінде behavior түсіну жеңілдейді.

  3. More accurate static analysis. Compiler real issues-ке focus ете алады.

Білуге тұрарлық басқа attributes

  • [MaybeNullWhen(true)] method true return еткенде out немесе ref parameter null болуы мүмкін екенін көрсетеді.

  • [NotNullIfNotNull("param")] specified input parameter null болмаса, return value де null болмайтынын көрсетеді.

  • [MemberNotNull("Field")] method exit болғанға дейін field немесе property initialized болатынын guarantees етеді.

  • [DoesNotReturnIf(true)] annotated Boolean parameter true болса, method never returns екенін көрсетеді, әдетте exception throws болғандықтан.

Қалай бастауға болады

.NET 5 және later ішінде бұл attributes built in.

Оларды behavior жоғарыдағы contracts-қа сәйкес methods-қа қосыңыз. Бұл runtime behavior өзгертпей compiler-ге көбірек context береді.