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

查看:24
本文介绍了如何使用 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 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天全站免登陆