How to remove compiler error with struct: quot;Use of unassigned local variablequot;(如何使用 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"是一个结构.如果它是一个类,我会简单地将它初始化为空.这个结构没有有意义的未初始化"状态,我不想支付初始化我立即丢弃的东西的性能成本,只是为了满足一个弱编译器.
代码(应该)完全正确:在初始化 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).
Mono 中的 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.DoSomething()
调用可以在没有明确分配 s
的情况下访问,因此您的代码已损坏.这不是编译器的错.如果 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
主体,但编译器仍会(正确地)进行编译上述代码出错,因为右大括号是可访问的,并且它是一个非 void 方法.
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: Use of unassigned local variable '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 删除编译器错误:“使用未分配的局部变量"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何使用 struct 删除编译器错误:“使用未分配的局部变量"
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- WebMatrix WebSecurity PasswordSalt 2022-01-01
- C#MongoDB使用Builders查找派生对象 2022-09-04
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- 如何用自己压缩一个 IEnumerable 2022-01-01
- C# 中多线程网络服务器的模式 2022-01-01
- 输入按键事件处理程序 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01