模式匹配和范围-If语句

时间:2019-12-13 09:41:26

标签: 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);
        }
        if (c is string mystring) {
         Console.WriteLine(mystring);
        }
    }

https://dotnetfiddle.net/tUTcOR

尝试编译以上代码将产生编译时错误:

  

已经定义了一个名为“ 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语句的已定义行为。

     

由于明确地设置了true的机制,因此在相应的if语句为true时分配了变量c和s。

https://docs.microsoft.com/en-us/dotnet/csharp/pattern-matching


现在给出以上说明,我想记下两个具体点,并提供另一个代码段:

  

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

AND

  

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

public static void Main()
{
    string a = "sdasd";
    object b = (object)a;
    object c = (object)a;

    if (b is string mystring) {
     Console.WriteLine(mystring);
    }else if (c is string mystringg)  {
     Console.WriteLine(mystringg);
    }else if (c is int mystringg) {
     Console.WriteLine(mystringg.ToString());
    }

}

https://dotnetfiddle.net/FFZhyl

因此,假设c is string mystringgc is int mystringg是在单独的范围内定义的(按照上面提到的第一个引号),并且两者的取值决不能等于true(或为)只能初始化这两者之一(按照上面的第二个引号),为什么上面的代码不能编译?

1 个答案:

答案 0 :(得分:2)

注意此段:

  

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

     

这意味着在if语句中声明的变量与if语句(在这种情况下为方法)处于同一范围内。此行为并非特定于模式匹配,而是变量范围以及if和else的已定义行为声明。

这意味着mystring具有方法范围。如果您在Sharplab.io中测试代码,则会看到以下代码:

    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);
    }