为什么这(NULL ||!的TryParse)条件导致“未分配使用局部变量”?(Why does t

2019-09-01 13:14发布

下面的代码会导致在使用未分配的局部变量“numberOfGroups”:

int numberOfGroups;
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups))
{
    numberOfGroups = 10;
}

但是,此代码工作正常(虽然, ReSharper的说= 10是多余的):

int numberOfGroups = 10;
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups))
{
    numberOfGroups = 10;
}

我失去了一些东西,或者编译器不喜欢我||

我已经缩小下来到dynamic造成的问题( options是在我上面的代码中动态变量)。 现在的问题仍然存在, 为什么我能做到这一点呢

此代码不能编译:

internal class Program
{
    #region Static Methods

    private static void Main(string[] args)
    {
        dynamic myString = args[0];

        int myInt;
        if(myString == null || !int.TryParse(myString, out myInt))
        {
            myInt = 10;
        }

        Console.WriteLine(myInt);
    }

    #endregion
}

然而,这段代码

internal class Program
{
    #region Static Methods

    private static void Main(string[] args)
    {
        var myString = args[0]; // var would be string

        int myInt;
        if(myString == null || !int.TryParse(myString, out myInt))
        {
            myInt = 10;
        }

        Console.WriteLine(myInt);
    }

    #endregion
}

我没想到dynamic将是这一个因素。

Answer 1:

我敢肯定,这是一个编译器错误。 - 尼斯找到!

编辑:这是不是一个错误,因为Quartermeister证明; 动态有可能实现一个奇怪的true操作者这可能会导致y永远不会被初始化。

这里有一个最小的摄制:

class Program
{
    static bool M(out int x) 
    { 
        x = 123; 
        return true; 
    }
    static int N(dynamic d)
    {
        int y;
        if(d || M(out y))
            y = 10;
        return y; 
    }
}

我不明白为什么这应该是非法的; 如果更换动态的布尔它编译就好了。

实际上,我与C#队明天会议; 我要把它提到他们。 道歉的错误!



Answer 2:

这是可能的变量是未分配如果动态表达式的值是与过载的类型的true操作者

|| 运营商将调用true运营商来决定是否评估右侧,然后if语句将调用true运营商来决定是否评估其身。 对于一个正常的bool ,这将始终返回相同的结果,因此只有一个将被评估,但对于用户定义的运营商没有这样的保证!

建立关埃里克利珀的清样,这里是演示既没有路径将被执行,并且变量将具有其初始值的情况下的短期和完整的程序:

using System;

class Program
{
    static bool M(out int x)
    {
        x = 123;
        return true;
    }

    static int N(dynamic d)
    {
        int y = 3;
        if (d || M(out y))
            y = 10;
        return y;
    }

    static void Main(string[] args)
    {
        var result = N(new EvilBool());
        // Prints 3!
        Console.WriteLine(result);
    }
}

class EvilBool
{
    private bool value;

    public static bool operator true(EvilBool b)
    {
        // Return true the first time this is called
        // and false the second time
        b.value = !b.value;
        return b.value;
    }

    public static bool operator false(EvilBool b)
    {
        throw new NotImplementedException();
    }
}


Answer 3:

从MSDN (重点煤矿):

动态类型使得能够在其中发生它绕过编译时类型检查的操作。 相反,这些操作都是在运行时解决 。 动态型简化了访问到COM API,例如办公自动化的API,并且还动态API,如IronPython的库和到HTML文档对象模型(DOM)。

类型的动态行为就像在大多数情况下类型的对象。 但是, 包含dynamic类型的表达式操作不解决或类型由编译器检查。

由于编译器没有类型检查或解析包含类型的动态表达的任何操作,也不能保证该变量将通过使用被分配TryParse()



文章来源: Why does this (null || !TryParse) conditional result in “use of unassigned local variable”?