【问题标题】:C# error from redeclaration of Pattern Matching variable in conditional在条件中重新声明模式匹配变量导致的 C# 错误
【发布时间】:2019-08-30 13:47:57
【问题描述】:

以下代码给出错误:“不能在此范围内声明名为 'ac' 的本地或参数,因为该名称在封闭的本地范围中用于定义本地或参数”。

    if (action is ActionRegisterNewDevice ac)
    {
        state = state.ShallowCopy();
        // Initialise the device to off
        state.DeviceOn[ac.ObjectId] = false;
    }
    else if (action is ActionOnMouseDown ac)
    {
        state = state.ShallowCopy();
        // toggle the state of the device
        state.DeviceOn[ac.ObjectId] = !DeviceSelectors.Device_is_on(state, ac.ObjectId);
    }

我的印象(显然是错误的)第一个条件是一个单独的范围。看起来模式匹配,即使是假的,仍然声明变量ac

但是the documentation 说:

模式匹配表达式的语言规则可帮助您避免 滥用匹配表达式的结果。在上面的例子中, 变量 s、c 和 r 仅在范围内,并且在 相应的模式匹配表达式具有真实的结果。如果你试试 要在另一个位置使用任一变量,您的代码会生成 编译器错误。

这个错误显然只能通过将第二个 ac 重命名为其他名称来解决。它是否正确?我误解了文档吗?

【问题讨论】:

  • 有什么问题?
  • @GaryStewart 已澄清我想要澄清。请问我对文档有什么误解。

标签: c# unity3d


【解决方案1】:

您应该重写代码以使用 switch 语句来获得您想要的行为:

void Main()
{
    Print("Hello world");
    Print(42);
}

static void Print(object o)
{
    switch (o)
    {
        // Note that I am reusing the variable name "value" in each case.
        case string value:
            Console.WriteLine("STRING: " + value);
            break;

        case int value:
            Console.WriteLine("INT: " + value.ToString());
            break;
    }
}

要回答您为何不能在 if...else... 中执行此操作的问题,请参阅您链接到的文档:

变量 s 在 ComputeAreaModernIs 方法的范围内。这是因为 if 语句的每个分支都为变量建立了单独的范围。但是,if 语句本身没有。

【讨论】:

  • 文档中的示例显示它使用if-else if。我想了解为什么我的代码不能像文档所说的那样工作......也许我误解了文档?
  • 文档中的示例并没有显示 - 它们使用 3 个不同的变量:Square sCircle cRectangle r。基本上,它不起作用,因为 if 语句不会创建新范围。我已经更新了我的答案来回答你提出的问题:)
  • 谢谢@RB。我习惯于 TypeScript 中的 Type Guards,您甚至不需要分配新变量:您在该范围内输入的变量具有新的缩小类型:typescriptlang.org/docs/handbook/… 我已经放入了一个 switch 语句,它效果很好。再次感谢。
猜你喜欢
  • 2022-08-17
  • 2019-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
相关资源
最近更新 更多