为什么这个程序只产生三个警告?

Why does this program only produce three warnings?

public class Program
{
     public static void main(String[] args)
     {
         string message = "This is a message";
         int number = 6;
         object obj = null;
         int? nullable = (int?)12;
     }
}

此程序的前三个变量声明抛出以下警告:

The variable 'X' is assigned but its value is never used

然而,最后声明:

int? nullable = (int?)12;

不抛出任何东西。这是为什么?

警告是最佳实践建议,并非真正的错误。 Visual studio 足够聪明,可以看到您创建了变量但从未使用过它们,因此它们毫无用处。建议您摆脱它们,因为您不使用它们。

如果你真的对它们做了一些事情,那么错误就会消失。例如,如果您说:

number += nullable;

将消除 1 个错误。如果你做了类似的事情:

message = message + " and this is more message";

它将消除另一个错误。

我相信它看到了整数?作为一个对象,并且由于您将其转换为可为 null 的变量,因此它无法确定它是否已被使用过。我认为它与转换有更多关系,只是没有被捕获为错误,因为它无法判断您是否在其他地方引用了该变量。

我认为它相当于这样的东西:

var a = new SomeClass();
var b = a;

既然不能判断a是否真的被使用过,那么就不报错了。如果你把它和一个真正的 class 放在一起,它也不会显示错误。

您看到的警告仅在编译器可以证明用于初始化变量的表达式不可能导致任何副作用的情况下显示。当您只是将文字字符串、整数或 null 值分配给变量时,编译器知道这些东西中的 none 可能会导致副作用。不过,对于你的最后一个值,你不仅仅是在分配一个字面值;您也在使用类型的显式运算符,就编译器而言,该运算符只是一些可以执行 任何事情 的代码。例如,它可能会导致相关的副作用(它不会,但编译器不知道),这将使该行不再多余。

似乎没有显示警告,因为带有可为空的行实际上在赋值之前执行了操作。例如,以下代码仅对名为 number 的变量生成警告。这似乎是合乎逻辑的,因为带有警告的行在当前代码中确实没有用。其他行可能会在执行期间做一些事情,不会是 "optimized out"。要使用调试器广告在发布模式下测试它 运行 您的代码,您会看到所有有警告的行都被跳过 ("optimized")

class Program
{
    static void Main(string[] args)
    {
        string message = ';'.ToString();
        int number = 6;
        object obj = (object)(new t());
        int? nullable = (int?)12;
    }
    class t
    { }
}

话虽如此。可空它没有优化,因为存在从 int '12' 到 int? 的转换。由于它是真正的演员表而不是 "useless cast" 需要在 运行 时间内进行操作。