2012-05-15 6 views
9

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

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

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

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

ответ

17

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

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

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

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

«Эй,» говорит пользователю во время отладки, «Интересно, что БлаБла возвращение?"Но нет никакого простого способа проверить возвращаемое значение в отладчика, так что пользователи очень часто делают это:.

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

, а затем использовать местные жители или смотреть окна для изучения ТЕМП Темп является никогда не используется в любом месте еще в функции, поэтому он произвел раздражающее «назначен, но не читать» предупреждение

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

  1. I на самом деле найти эти предупреждения полезными, когда они даны в MonoDevelop.
  2. Любой может подавить само предупреждение (по общему признанию, они также будут подавлять их для неиспользуемых постоянных заданий времени компиляции - возможно, для этого должно быть отдельное предупреждение?).

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

+0

Теперь, когда вы можете [просмотреть возвращаемые значения в отладчике visual studio] (https://msdn.microsoft.com/en-us/library/dn323257.aspx), есть ли причина, по которой это предупреждение отключено? – cloudshao

+2

Любой способ включить предупреждение? – Xonatron

+1

Я пришел сюда, спрашивая, знает ли кто, как вернуть предупреждение ... это потому, что разработчики инициируют переменные, которые тяжелы и не используют их (тяжелым, я имею в виду создание экземпляра класса, который делает много вещей, когда это не так необходимо) –

2

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

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

+1

Но вы можете сохранить вызов 'new object()' без присвоения результата переменной. – phoog

2

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

+0

Это имеет смысл, но вы бы подумали, что компилятор будет знать достаточно, чтобы знать, что системный объект, такой как 'object', не будет иметь побочных эффектов. –

+1

@StevenBurnap компилятор не очень умен, когда дело доходит до «очевидной» информации. Как правило, это потому, что преимущество добавления логики для отслеживания таких вещей (небольших) не перевешивает стоимость сложной (большей) компиляции. – phoog

+0

Я не уверен в этом ответе. Эффекты запуска компилятора могут быть сохранены таким образом: 'void Main (string [] args) {new object(); int y = 0; } '. – phoog

1

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

0

Может быть, так как 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 
    } 
} 
+1

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

Смежные вопросы