如何使用struct移除编译器错误:“使用未分配的本地变量" [英] How to remove compiler error with struct: "Use of unassigned local variable"
问题描述
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 valuefalse
.
这里的表达式是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屋!