如何使用struct移除编译器错误:“使用未分配的本地变量" [英] How to remove compiler error with struct: "Use of unassigned local variable"

查看:62
本文介绍了如何使用struct移除编译器错误:“使用未分配的本地变量"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C#编译器有点...过时了...并且不会执行静态分析.因此,它似乎在貌似的正确代码上中断了:

The C# compiler is a bit ... old fashioned ... and won't do static analysis. So it breaks on seemingly correct code like this:

MyStruct s;
bool inited = false;
foreach( Something foo in ACollection )
{
  if( foo.Test() )
    continue;
  if( inited )
    s.DoSomething();
  else
  {
    s = foo.GetMeAnS();
    inited = true;
  }
}

注意:异常的问题是"s"是一个结构.如果它是一个类,我只需将其初始化为null.该结构没有有意义的未初始化"状态,我不想为立即创建一个我立即丢弃的东西而付出的性能代价,只是为了满足弱编译器的需要.

(应该是)代码完全正确:在初始化s之前,无法访问s. (我已经从实际代码中复制/粘贴了,但是为了简单起见,删除了长方法名).

The code (should be) fully correct: it's impossible to access s until s has been inited. (I've copy/pasted from actual code, but edited-out long method names for simplicity).

C#编译器曾经允许这样做,但是现在不允许了.除了编译器,什么都没有改变,编译器现在会给未分配的变量带来错误.

C# compiler in Mono used to allow this, but now it doesn't. Nothing has changed except the compiler, which now gives an error on unassigned variable.

是否存在一种代码方法来告诉它关闭并关注自己的业务? :)我不想摆弄不断变化的编译器设置(如果可能的话),因为代码是由其他人/组织编译的-我更喜欢一种解决问题的代码方法.

Is there a code way to tell it to shut up and mind its own business? :) I don't want to fiddle with changing compiler-settings (if possible) because the code is compiled by other people/orgs - I'd prefer a code way of fixing the problem.

推荐答案

有没有一种代码方法可以告诉它关闭并关注自己的业务?

Is there a code way to tell it to shut up and mind its own business?

编译器的业务正在实现C#规范.您编写的代码不应根据C#规范进行编译.在没有明确分配s的情况下,可以到达s.DoSomething()调用,因此您的代码已损坏.那不是编译器的错.如果Mono编译器使用允许它,那显然是一个错误,现在已经修复.

The compiler's business is implementing the C# specification. The code you've written should not compile according to the C# specification. The s.DoSomething() call is reachable without s being definitely assigned, therefore your code is broken. That's not the compiler's fault. If the Mono compiler used to allow it, that was a bug which has apparently now been fixed.

修复它的最简单方法是明确地赋值,当然:

The simplest way of fixing it is to definitely assign the value, of course:

MyStruct s = new MyStruct(); // Value will never actually be used

在很多情况下,我们(作为人类)可以说某些事情永远不会发生,但是编译器却不会.这是另一个示例:

There are plenty of cases where we (as humans) can tell that something will never happen, but the compiler can't. Here's another example:

public int Foo(int input)
{
    if (input >= 0)
    {
        return input;
    }
    else if (input < 0)
    {
        return -input;
    }
    // This is still reachable...
}

我们知道每个int输入都将进入那些if主体之一,但是编译器仍将(正确)给出上述代码的编译错误,因为右括号是可以到达的,这是一种非无效的方法.

We know that every int input will go into one of those if bodies, but the compiler will still (correctly) give a compilation error on the above code, because the closing brace is reachable and it's a non-void method.

您声称代码(应该)完全正确"是根据您的推理,而不是C#规范...并且编译器仅是为了关心后者.

Your claim that "The code (should be) fully correct" is according to your reasoning, not the C# specificiation... and the compiler is only meant to care about the latter.

需要注意的一件事:规范甚至不关心在某些情况下我们确实将inited设置为true的事实.即使总是的值为false,它仍然只是局部变量,而不是常量表达式.这是一个简单的示例,演示了没有循环:

One thing to note: the specification doesn't even care about the fact that we do actually set inited to true in some cases. Even if it always had the value of false, it's still just a local variable, not a constant expression. Here's a simple example demonstrating that with no loop:

static void Main()
{
    int x;
    bool condition = false;
    if (condition)
    {
        Console.WriteLine(x);
    }
}

这仍然会产生错误:错误CS0165:使用未分配的局部变量'x'"

This still gives an error: "error CS0165: Use of unassigned local variable 'x'"

来自C#5规范的8.7.1节:

From section 8.7.1 of the C# 5 specification:

如果if语句可访问并且布尔表达式不具有常量值false,则if语句的第一个嵌入式语句是可访问的.

The first embedded statement of an if statement is reachable if the if statement is reachable and the boolean expression does not have the constant value false.

这里的表达式是condition,它是一个局部变量.从技术上讲,局部变量不是常量表达式,即使它永远不会改变.如果改为使用局部常量,则它会 进行编译:

Here the expression is condition, which is a local variable. A local variable is not a constant expression in technical terms, even if it will never change. If you make it a local constant instead, it will compile:

static void Main()
{
    int x;
    const bool condition = false;
    if (condition)
    {
        Console.WriteLine(x);
    }
}

现在,有一个警告关于if语句的正文不可访问-但没有错误.

Now there's a warning about the body of the if statement being unreachable - but there's no error.

这篇关于如何使用struct移除编译器错误:“使用未分配的本地变量"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆