【问题标题】:Why does this program only produce three warnings?为什么这个程序只产生三个警告?
【发布时间】:2015-12-08 11:13:27
【问题描述】:
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;
     }
}

该程序的前三个变量声明引发以下警告:

变量“X”被赋值,但它的值从未被使用过

然而,最后一句话:

int? nullable = (int?)12;

不扔任何东西。这是为什么呢?

【问题讨论】:

  • 我正在使用 VS2015,我收到 4 个警告。
  • @JeroenVannevel 我正在使用 VS2012,我得到了三个。将发布屏幕截图。
  • 然后我认为它曾一度被窃听并且不再存在。不过,我无法立即找到有关错误修复的任何信息。
  • 为什么不在类级别声明变量然后分配它,你会看到它被解析或在类级别声明public string message = "This is a message"

标签: c# .net compilation warnings compiler-warnings


【解决方案1】:

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

如果你真的对它们做了什么,那么错误就会消失。例如,如果你说:

number += nullable;

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

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

它会消除另一个错误。

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

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

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

由于它无法判断 a 是否真的被使用过,所以它不会显示错误。如果你把它放在一个真正的类中,它也不会显示错误。

【讨论】:

  • 同样的原则也适用。因为你没有使用变量 obj,只是设置它。 Visual Studio 建议您将资源浪费在从未使用过的变量上。
  • 不过,我并不是真的在问如何摆脱这些警告。我想知道为什么有些警告没有出现。
  • 哦,我想我明白了,您在问为什么它没有在可空值上显示错误?
  • @Jonathan 我注意到你说你摆脱了所有 3 个错误,但你错过了一个。
  • @Jonathan 没错。这让我很困扰!
【解决方案2】:

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

【讨论】:

  • 这很有意义,但为什么他们会像@JeroenVannevel 评论的那样在 VS2015 上改变这种行为?
  • @MatiCicero 该操作实际上不会引起任何副作用,所以它在早期版本中没有提供警告的原因是它的算法根本没有足够复杂以意识到代码是多余的。显然他们改进了算法,因此在其他情况下它实际上可以表明代码不会引起副作用。
【解决方案3】:

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

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? 的转换。由于它是真正的演员表,而不是“无用演员表”,因此在运行时需要进行操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    • 2013-03-10
    • 2016-04-04
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多