在 'if' 内部初始化的局部变量在 C# 中 'if' 之后仍然可用

Local variable initialized inside 'if' is still available after that 'if' in C#

还没有找到这个问题的答案(可能是因为我找错了)。我只是想知道下面。为什么不能有这个代码:

if (obj is string str) {
    // do stuff
}
if (obj is string str) {
    // do stuff
}

这将引发以下错误:错误 CS0128 已在此范围内定义名为 'str' 的局部变量或函数

我知道我可以改用这个:

{
    if (obj is string str) {
        // do stuff
    }
}
{
    if (obj is string str) {
        // do stuff
    }
}

但它还有其他缺点,对我来说最大的是更多的代码行。

我猜是因为编译器实际上将代码(两者中的上部)转换为以下代码:

string str = obj as string;
if (str != null) {
    // do stuff
}

或者类似的东西。

如果是这种情况,我想知道为什么以及是否已经有比写作更好的方法:

if (obj is string str1) {
    // do stuff
}
if (obj is string str2) {
    // do stuff
}
if (obj is string str3) {
    // do stuff
}

希望有人能告诉我C#逻辑中的问题是什么以及处理它的方法。如果这样的问题已经存在,请 link 我真的找不到。

编辑: 因为这个用例被问到了。首先,我想知道 general 背后的逻辑,但其次,我现在有一个用例,由于某些原因,无法以不同方式处理。

这在我遇到的情况下会很有用,例如传递的不同数据,然后我执行特定于类型的操作 1 然后执行两者都需要的操作,然后执行另一个特定于类型的操作。

问题是,为什么会报错:"Error CS0128 A local variable or function named 'str' is already defined in this scope" .

答案是,代码if (obj is string str1)是声明变量和赋值的语法糖。

我为此使用了 sharplab.io

public class C 
{
    public void M() 
    {
        object obj = "Test string";
        
        if (obj is string str1)
        {
            Console.WriteLine($"{obj} is a string");
        }
    }
}

编译为:

public class C
{
    public void M()
    {
        object obj = "Test string";
        string text = obj as string;
        if (text != null)
        {
            Console.WriteLine(string.Format("{0} is a string", obj));
        }
    }
}

所以 obj 变量不是在内部作用域中声明的,而是在外部作用域中声明的。

仅建议另一种声明方式以避免编译错误:

你可以在条件外声明变量,然后像这样使用它:

string? str;

if ((str = obj as string) != null)
{
    // do stuff
}
if ((str = obj as string) != null)
{
    // do stuff
}

并没有好多少,但您可能更喜欢它。