C# 带模式匹配的CS0103和CS0136

C# 带模式匹配的CS0103和CS0136,c#,scope,c#-7.0,C#,Scope,C# 7.0,我有点困惑。为什么从一个侧面我变成了CS0103(变量不存在),从另一个侧面变成了CS0136(用自己的话-变量已经存在)并且在switch中声明了同名变量 此有效: var obj = new object(); switch (obj) { case string str: break; case object str: break; } var obj = new object(); switch (obj) { case str

我有点困惑。为什么从一个侧面我变成了
CS0103
(变量不存在),从另一个侧面变成了
CS0136
(用自己的话-变量已经存在)并且在switch中声明了同名变量

有效

var obj = new object();
switch (obj)
{
    case string str:
        break;

    case object str:
        break;
}
var obj = new object();
switch (obj)
{
    case string str: //<--- CS0136
        break;
}
string str = "";
这里出现编译错误CS0103
“名称“”在当前上下文中不存在”:

这里我变成了编译错误CS0136

var obj = new object();
switch (obj)
{
    case string str:
        break;

    case object str:
        break;
}
var obj = new object();
switch (obj)
{
    case string str: //<--- CS0136
        break;
}
string str = "";
var obj=新对象();
开关(obj)
{

case string str://这里有三条规则:

  • 局部变量的作用域通常是声明它的整个块。通过switch语句中的模式匹配引入的变量略窄于此,这就是为什么您能够同时拥有
    对象str
    字符串str
    的模式,但您不需要这些来演示这些特定的错误卢比
  • 不能在其作用域之外使用变量
  • 不能在具有相同名称的另一个局部变量的作用域中声明一个局部变量
您不需要模式匹配来演示这一点。这里有一个简单的方法,给出了CS0103错误:

void Method()
{
    {
        // Scope of str is the nested block.
        string str = "";
    }
    // str isn't in scope here, so you can't refer to it;
    // second bullet point
    if (str == "") {}
}
以下是CS0136的一个示例:

void Method()
{
    {
        // Can't declare this variable, because the str variable
        // declared later is already in scope
        string str = "";
    }
    // Scope of this variable is the whole method
    string str = "";
}

这里有三条规则:

  • 局部变量的作用域通常是声明它的整个块。通过switch语句中的模式匹配引入的变量略窄于此,这就是为什么您能够同时拥有
    对象str
    字符串str
    的模式,但您不需要这些来演示这些特定的错误卢比
  • 不能在其作用域之外使用变量
  • 不能在具有相同名称的另一个局部变量的作用域中声明一个局部变量
您不需要模式匹配来演示这一点。这里有一个简单的方法,给出了CS0103错误:

void Method()
{
    {
        // Scope of str is the nested block.
        string str = "";
    }
    // str isn't in scope here, so you can't refer to it;
    // second bullet point
    if (str == "") {}
}
以下是CS0136的一个示例:

void Method()
{
    {
        // Can't declare this variable, because the str variable
        // declared later is already in scope
        string str = "";
    }
    // Scope of this variable is the whole method
    string str = "";
}

请提供一个-听起来上下文在这里是相关的,特别是考虑到CS0136。虽然
str
的两个实例在
开关
外不可见(即
cs0103
),但为防止程序员混淆,声明另一个
str
也是不合法的(即
CS0136
)。如果显式引入新范围(
{string str=”“;}
),则是合法的。在
开关
中允许多个不同的
str
声明可能被认为是不一致的,但在这种情况下,混淆它们的风险是最小的,因为块在词汇上是分开的。@JonSkeet上下文不相关,只是理论(通过编码注意,这会变成错误,但这不是问题)。这个问题对应于mCve。它至少让人困惑。如果您为每个错误案例提供了完整的代码(准备进行复制/粘贴/编译),那么会更容易提供帮助。我现在明白您的意思了,但是整个“注释中”部分确实令人困惑。@Jonsket好的,我将修改问题请提供一个-听起来上下文在这里是相关的,特别是考虑到CS0136。而
str
的两个实例在
开关
之外不可见(这就是
cs0103
),声明另一个
str
也不合法,以防止程序员混淆(即
cs0136
)。如果显式引入新范围(
{string str=”“;}
),则是合法的。在
开关
中允许多个不同的
str
声明可能被认为是不一致的,但在这种情况下,混淆它们的风险是最小的,因为块在词汇上是分开的。@JonSkeet上下文不相关,只是理论(通过编码注意,这会变成错误,但这不是问题)。这个问题对应于mCve。它至少让人困惑。如果您为每个错误案例提供了完整的代码(准备进行复制/粘贴/编译),那么会更容易提供帮助。我现在明白您的意思了,但是整个“注释中”“部分确实令人困惑。@JonSkeet好的,我会修改问题,所以从你的回答来看-我的作用域是整个方法和开关,对吗?@Rekshino:差不多。事实上,开关语句中模式匹配的作用域较小,这就是为什么允许同时使用
对象str
字符串str
。谢谢提醒-我将编辑my第一个要点。这是另一个让它在没有模式匹配的情况下更好地显示的东西。我想误解来自于暗示范围向下(不是整个方法)@Rekshino:这就解释了第二个错误。第一个错误是变量超出范围。所以从你的回答来看-我的范围是整个方法和开关,对吗?@Rekshino:差不多。事实上,switch语句中模式匹配的范围较小,这就是为什么你可以同时拥有
对象str
字符串str
。感谢您的提醒-我将编辑我的第一个要点。这是另一个让这一点在没有模式匹配的情况下更好地显示的东西。我想误解是因为暗示作用域向下(而不是整个方法)@Rekshino:这解释了第二个错误。第一个错误是变量超出作用域的问题。