Почему нет предупреждения для этой неиспользуемой переменной?

При компиляции следующей программы в VS2010, VS2008 или MonoDevelop в Windows, я получаю предупреждение CS0219, "Переменная 'y' назначается, но ее значение никогда не используется".

namespace Problem
{
    public class Program
    {        
        private static void Main(string[] args)
        {
            object x = new object();
            int y = 0;
        }
    }
}

Почему при компиляции в Visual Studio нет предупреждения для x?

Интересно, что я получаю предупреждения CS0219 для x и y при компиляции в MonoDevelop на Mac OS X.

Ответ 1

Оказывается, это предупреждение подавляется, когда правая сторона операции присваивания не является константой времени компиляции.

Сообщение с удаленной записью на сайте обратной связи Microsoft Visual Studio объяснило это тем, что у них было много жалоб от людей, которые просто назначали переменные, чтобы они могли видеть, какой вызов метода возвращался во время отладки, и обнаружил, что предупреждение раздражает:

Подавление "назначенного, но никогда не используемого" предупреждения в этом случае было мотивировано отзывами пользователей, которые это делают:

int Blah(){
    // blah
    BlahBlah(x, y, z)
    // blah
    // blah
}

"Эй, - говорит пользователь во время отладки, - мне интересно, что такое BlahBlah возвращение?" Но нет простого способа проверить возвращаемое значение в отладчик, поэтому пользователи очень часто это делают:

int Blah()
{
    // blah
    int temp = BlahBlah(x, y, z)
    // blah
    // blah
}

а затем используйте локали или окно просмотра, чтобы изучить temp. Темп никогда не использовалась нигде в функции, поэтому она вызывала раздражающее "назначено, но не прочитано".

Я думаю, что это немного стыдно, поскольку:

  • Я действительно нахожу эти предупреждения полезными, когда они указаны в MonoDevelop.
  • Каждый может подавить предупреждение (правда, они также будут подавлять их для неиспользуемых постоянных заданий времени компиляции - возможно, для этого должно быть отдельное предупреждение?).

В любом случае, я понимаю, что вы не можете угодить всем.

Ответ 2

Я мог бы отключиться отсюда, но я думаю, что потому, что y задан только, тогда как x создается каким-то нетривиальным - экземпляры могут включать отдельные действия в методе New(), и поскольку создание экземпляра переменной может иметь сторону -эффекты, это не считается неиспользованным. В вашем случае это просто базовый объект(), поэтому нет никакого эффекта, но, возможно, компилятор недостаточно умен, чтобы отличить его.

С y, с другой стороны, никаких побочных эффектов для экземпляра нет, поэтому он считается неиспользуемым - путь кода приложения не изменится, если он полностью удален.

Ответ 3

Моя догадка заключается в том, что, будучи x ссылочным типом, компилятор не показывает никаких предупреждений, поскольку конструктор может выполнять некоторую операцию, которая вполне может быть "значимой"; напротив, y является типом значения, значение которого присваивается, но никогда не используется, поэтому компилятор легко сказать вам, что нет смысла делать это, если вы не собираетесь ссылаться на него по строке.

Ответ 4

Resharper также предупредит вас, что x не используется.

Ответ 5

Может быть, так как x является ссылочным типом и поэтому хранится в куче, что он предотвратит сбор мусора этого объекта до тех пор, пока x не выйдет из области видимости.

например:

void main(string[] args)
{
    object x = new object();
    while (true)
    {
        // some threading stuff
        // x is never garbage collected
    }
}

В отличие от:

void main(string[] args)
{
    new object();
    while (true)
    {
        // some threading stuff
        // the unreferenced object IS garbage collected
    }
}

Ответ 6

у в стеке, х в куче (подсказка: х использует новое ключевое слово). Таким образом, некоторые предупреждения отладчика/компилятора, вероятно, считают, что кучи/глобальные переменные, такие как x, должны быть оставлены на усмотрение программиста, поскольку низкоуровневый код или тест отладки могут играть с ними за кулисами. Но такая переменная стека, как y, полностью находится под контролем компилятора и может легко обнаружить неиспользуемую избыточную переменную.

Ответ 7

Eclipse рассмотрит случай не использованный.