dotnet/roslyn

Better codegen for conditional-access + pattern checks.

Open

#69,411 创建于 2023年8月5日

在 GitHub 查看
 (7 评论) (5 反应) (0 负责人)C# (4,257 fork)batch import
Area-CompilersCode Gen Qualityhelp wanted

仓库指标

Star
 (20,414 star)
PR 合并指标
 (平均合并 6天 17小时) (30 天内合并 256 个 PR)

描述

Given code like the following:

    static void Main(string[] args)
    {
        if (args?.Length is 1)
            Console.WriteLine(true);
    }

The compiler currently compiles that similarly to the following:

int? __t1 = __argsTemp?.Length;
if (__t1.HasValue && __t1.GetValueOrDefault() == 1) ...

While correct, this appears to be unnecessarily expensive. Specifically, because the pattern itself does not have null in its acceptance-set, there's no need to actually produce and instantiate a nullable-int on the stack just to test that instead. Rather, the above would be better compiled to something similar to:

if (__argsTemp != null && __argsTemp.Length is 1)

In other words, once the null check is performed, if it is null, then the value of args?.Length would be known to be null, which could never match 1, so no further checks are necessary. However, if the null check is performed and the value is not null, then it is known that it is safe to access members of it directly. This avoids unnecessary nullable allocations on the stack in either case.

Note: this could also be done for operators like == and != on primitive types, when the comparands are constants.

贡献者指南