模式匹配动态变量导致的编译器错误

Compiler error by pattern matching dynamic variable

为什么将 c != null && 结果添加到 c1 的编译器错误 CS0165?目标是.NET5.0.

var a = "";
if(a is string a1)
{
    if("".Contains(a1)) return; //OK
}
dynamic b = "";
if(b is string b1)
{
    if("".Contains(b1)) return; //OK
}

dynamic c = "";
if(c != null && c is string c1)
{
    if("".Contains(c1)) return; //CS0165 Using not assigned variable??
}

dynamic d = "";
if(d != null && d is string)
{
    var d1 = d;
    if("".Contains(d1)) return; //OK

    var d11 = d as string;
    if("".Contains(d11)) return; //OK
}

更新:
所以根据Luaan的回答,整个语句将不会被评估,不仅仅是动态对象的右侧

dynamic d = "";
var c = "";
if(c is string c1 && true && d != null && c is string f1)
{
    if("".Contains(c1)) return; //error
                
    if("".Contains(f1)) return; //error

    var d1 = d;
    if("".Contains(d1)) return; //OK
    var d11 = d as string;
    if("".Contains(d11)) return; //OK
}

&& 在动态操作数的编译时不会短路。

根据规范 (Conditional logical operators):

If an operand of a conditional logical operator has the compile-time type dynamic, then the expression is dynamically bound (Dynamic binding). In this case the compile-time type of the expression is dynamic, and the resolution described below will take place at run-time using the run-time type of those operands that have the compile-time type dynamic.

c != null && c is string c1是一个动态表达式,所以它是动态绑定的,静态编译器不能保证c1被赋值。

当然,这在实践中并不重要,因为您的 null 检查完全是多余的 - is string 已经确保该值不为 null。

这里的问题是编译器无法以任何方式验证逻辑运算符是否以某种奇怪的方式重载,这种方式碰巧从不评估逻辑表达式的右侧,同时仍然成功返回 true.这就是你得到编译时错误的原因。