动态出现意外的编译时错误

dav*_*v_i 19 c# dynamic c#-5.0 visual-studio-2012

澄清问题:我不是在寻找如何解决这个问题的答案(下面列出了几个),但是为什么会这样.

我希望编译以下代码:

struct Alice
{
    public string Alpha;
    public string Beta;
}

struct Bob
{
    public long Gamma;
}

static object Foo(dynamic alice)
{
    decimal alpha;
    long beta;

    if (!decimal.TryParse(alice.Alpha, out alpha) // *
        || !long.TryParse(alice.Beta, out beta)) // **
    {
        return alice;
    }

    var bob = new Bob { Gamma = beta }; // ***

    // do some stuff with alice and bob

    return alice;
}
Run Code Online (Sandbox Code Playgroud)

但是,抛出以下编译时错误// ***:

使用未分配的局部变量'beta'

我可以在以下情况下编译程序:

  1. 如果我更改签名

    static object Foo(Alice alice)

  2. 显式铸造的线条// *// **,例如:

    !long.TryParse((string)alice.Beta, out beta).

  3. 删除decimal.TryParse联机// *.

  4. 更换短路或|||.感谢HansPassant

  5. 交换TryParses周围

  6. 把结果拉TryParsebools 感谢克里斯

  7. 为其分配默认值 beta

我错过了一些明显的东西,或者是否有一些微妙的事情,或者这是一个错误?

Lan*_*kin 12

我不确定答案,但对我来说,它看起来像编译器错误或"按设计"问题.

我稍微使用了你的样本,一点一点地减少了它,这就是它留下的东西:

    private static bool Default<T>(out T result)
    {
        result = default(T);
        return true;
    }

    private static void Foo()
    {
        int result;

        if (true || Default(out result))
        {
            return;
        }

        Console.WriteLine(result);
    }
Run Code Online (Sandbox Code Playgroud)

哪个也失败了

错误CS0165:使用未分配的局部变量'result'

你可以玩int resultFoo检查任何你想要的类型.

请注意没有用处dynamic,请注意true应立即返回的分支.

所以对我来说,看起来VS.Net编译器在这里"不够智能".

这段代码有什么用 - 它可以在.Net 4之前用编译器编译(使用csc.exe适当的框架),所以结果如下:

  • .Net 2.0

建立好,警告:

警告CS0429:检测到无法访问的表达式代码

警告CS0162:检测到无法访问的代码

  • .Net 3.5

构建失败:

错误CS0165:使用未分配的局部变量'result'

因此,如果它一个错误,它出现在.NET 2和.NET 3.5之间

  • 有趣的分析.我们需要以某种方式召唤Eric Lippert,给我们一个明确的评论!:) (7认同)
  • 同样值得注意的是,仿制药在这里似乎也没有必要(即只是`Default(out int result)`似乎表现出这种行为). (2认同)