C# 模式匹配和scope-If语句

C# 模式匹配和scope-If语句,c#,c#-7.0,c#-8.0,C#,C# 7.0,C# 8.0,因此,我一直在绞尽脑汁,或者更确切地说,是因为以下代码片段: public static void Main() { string a = "sdasd"; object b = (object)a; object c = (object)a; if (b is string mystring) { Console.WriteLine(mystring);

因此,我一直在绞尽脑汁,或者更确切地说,是因为以下代码片段:

public static void Main()
    {
        string a = "sdasd";
        object b = (object)a;
        object c = (object)a;
        
        if (b is string mystring) {
         Console.WriteLine(mystring);
        }
        if (c is string mystring) {
         Console.WriteLine(mystring);
        }
    }
()

试图编译上述代码将产生编译时错误:

名为“mystring”的局部变量或函数已定义或在此范围内

我相信,如果语句的表达式中声明的任何内容的作用域与所述语句的作用域相同,那么在上面的示例中,“main”将定义作用域。这是有道理的


参考MSDN文件:

public static double ComputeAreaModernIs(object shape)
{
    if (shape is Square s)
        return s.Side * s.Side;
    else if (shape is Circle c)
        return c.Radius * c.Radius * Math.PI;
    else if (shape is Rectangle r)
        return r.Height * r.Length;
    // elided
    throw new ArgumentException(
        message: "shape is not a recognized shape",
        paramName: nameof(shape));
}
让我们从范围开始,详细研究这两个规则。变量c仅在第一个if语句的else分支的作用域中。变量s在ComputeAreaModernIs方法的作用域中。这是因为if语句的每个分支都为变量建立了单独的作用域。但是,if语句本身并没有。这意味着if语句中声明的变量与if语句(本例中的方法)在同一范围内。此行为不是特定于模式匹配的,而是为变量范围以及if和else语句定义的行为

变量c和s在各自的if语句为true时被赋值,这是因为明确指定了when true机制

()


现在给出上述解释,我想注意两点,并提供另一个代码片段:

这是因为if语句的每个分支都为变量建立了单独的作用域

当相应的if语句为真时,将分配变量c和s

()

因此,鉴于
c是string mystringg
,而
c是int mystringg
是在不同的范围内定义的(根据上面提到的第一个引号),并且两者都不能计算为
true
(或),这意味着只有其中一个将被初始化(根据上面的第二个引号),为什么上面的代码没有编译?

请注意以下部分:

这是因为if语句的每个分支都为变量建立了单独的作用域。但是,if语句本身并没有

这意味着if语句中声明的变量与if语句(本例中的方法)在同一范围内。此行为不是特定于模式匹配的,而是为变量范围以及if和else语句定义的行为

这意味着
mystring
具有方法作用域。如果在中测试代码,您将看到以下代码:

    string a = "sdasd";
    object b = (object)a;
    object c = (object)a;

    if (b is string mystring) {
       Console.WriteLine(mystring);
    }
    if (c is string mystring1) {
       Console.WriteLine(mystring1);
    }
翻译为:

    string text = "sdasd";
    object obj = text;
    object obj2 = text;
    string text2 = obj as string;
    if (text2 != null)
    {
        Console.WriteLine(text2);
    }
    string text3 = obj2 as string;
    if (text3 != null)
    {
        Console.WriteLine(text3);
    }
请注意这一部分:

这是因为if语句的每个分支都为变量建立了单独的作用域。但是,if语句本身并没有

这意味着if语句中声明的变量与if语句(本例中的方法)在同一范围内。此行为不是特定于模式匹配的,而是为变量范围以及if和else语句定义的行为

这意味着
mystring
具有方法作用域。如果在中测试代码,您将看到以下代码:

    string a = "sdasd";
    object b = (object)a;
    object c = (object)a;

    if (b is string mystring) {
       Console.WriteLine(mystring);
    }
    if (c is string mystring1) {
       Console.WriteLine(mystring1);
    }
翻译为:

    string text = "sdasd";
    object obj = text;
    object obj2 = text;
    string text2 = obj as string;
    if (text2 != null)
    {
        Console.WriteLine(text2);
    }
    string text3 = obj2 as string;
    if (text3 != null)
    {
        Console.WriteLine(text3);
    }

您尚未在括号内输入新范围。例如,可以使用与声明out变量作为
TryParse
的一部分相同的方法。在第一个
if
语句之后尝试访问
myString
“if语句中声明的变量与if语句在同一范围内”对我来说似乎非常清楚。您引用了文档中的内容,这正好解释了为什么会发生这种情况
c
被重新定义了作用域,因为它仅作为
if
语句的一个分支可用。您尚未在括号内输入新的作用域。例如,可以使用与声明out变量作为
TryParse
的一部分相同的方法。在第一个
if
语句之后尝试访问
myString
“if语句中声明的变量与if语句在同一范围内”对我来说似乎非常清楚。您引用了文档中的内容,这正好解释了为什么会发生这种情况
c
被重新定义了范围,因为它仅作为
if
语句的一个分支可用。啊,这是有意义的。不知道为什么我没有反编译单个模式匹配express,并查看输出。谢谢。啊,这很有道理。不知道为什么我没有反编译单个模式匹配express,并查看输出。谢谢