2009-02-23 2 views
13

Я попытался помечать свойство коллекции в классе как Устаревшее, чтобы найти все события и сохранить сокращающийся список вещей, которые нужно исправить в моем предупреждающем списке, из-за того, что нам нужно заменить это свойство коллекции чем-то другим.Почему свойства C# collection-properties не отмечены как устаревшие при вызове на них свойств?


Редактировать: Я представил это через Microsoft Connect, issue #417159.

Редактировать 16.11.2010: Проверено, что это теперь работает в компиляторе C# 4.0, как при компиляции для .NET 3.5, так и 4.0. Я получаю 4 предупреждения в опубликованном коде, в том числе с комментарием «Не в порядке?».


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

Вот пример программа, готовая для компиляции в Visual Studio 2008.

Примечания четыре линии ближе к концу помеченного # 1- # 4, из них, я бы ожидать, что все из них, чтобы сообщить о том, что используемое свойство было устаревшим, но # 3 - нет, и кажется, что если я просто перейду к свойствам или методам коллекции напрямую, использование самого свойства не будет помечено как устаревшее. Обратите внимание, что # 3 и # 4 ссылаются на одно и то же свойство, а # 4 помечены как использование устаревшего свойства, а # 3 - нет. Тесты показывают, что если в выражении я получаю доступ к свойствам или методам коллекции, которые возвращает свойство, компилятор не жалуется.

Это ошибка, или это «скрытый камень» компилятора C#, о котором я не знал?

using System; 
using System.Collections.Generic; 

namespace TestApp 
{ 
    public abstract class BaseClass 
    { 
     [Obsolete] 
     public abstract String Value 
     { 
      get; 
     } 

     [Obsolete] 
     public abstract String[] ValueArray 
     { 
      get; 
     } 

     [Obsolete] 
     public abstract List<String> ValueList 
     { 
      get; 
     } 
    } 

    public class DerivedClass : BaseClass 
    { 
     [Obsolete] 
     public override String Value 
     { 
      get 
      { 
       return "Test"; 
      } 
     } 

     [Obsolete] 
     public override String[] ValueArray 
     { 
      get 
      { 
       return new[] { "A", "B" }; 
      } 
     } 

     [Obsolete] 
     public override List<String> ValueList 
     { 
      get 
      { 
       return new List<String>(new[] { "A", "B" }); 
      } 
     } 
    } 

    public class Program 
    { 
     public static void Main(String[] args) 
     { 
      BaseClass bc = new DerivedClass(); 
      Console.Out.WriteLine(bc.Value);    // #1 - OK 
      Console.Out.WriteLine(bc.ValueArray.Length); // #2 - OK 
      Console.Out.WriteLine(bc.ValueList.Count); // #3 - Not OK? 
      List<String> list = bc.ValueList;   // #4 - OK 
     } 
    } 
} 
+0

Я пометил свой «подключить», как подтверждено и дали ему оценку ... –

+0

Кстати, я бы не ожидать исправления до C# 4.0 ; будет ли код компилироваться в 2.0? Возможно, попробуйте компилятор 2.0 ... –

+0

nah, мы сделаем это, я только случайно обнаружил это при попытке использовать ObsoleteAttribute в качестве быстрого способа получить список «todo» для вещей, которые нужно исправить, прежде чем мы перейдем к рефакторинг. –

ответ

14

Хм ... похоже на ошибку компилятора! Он терпит неудачу следующее (ECMA 334v4):

24.4.3 Устаревший атрибут Атрибут Устаревшие используется для обозначения типов и членов типов, которые не должны больше не будет использоваться. Если в программе используется тип или член , который украшен атрибутом Obsolete, то компилятор должен выдать предупреждение или , чтобы предупредить разработчика, , чтобы можно было устранить код нарушения. В частности, компилятор должен выдать предупреждение, если не указан параметр ошибки , или если параметр ошибки имеет значение и имеет значение false. Компилятор должен выдать ошибку компиляции , если указан параметр ошибки и имеет значение true.

В частности, при маркировке true он должен выдавать ошибку, а это не так. Хорошая находка! Вы можете сообщить об этом на «connect», или если вы не хотите, чтобы боль при настройке входа в систему, сообщите мне, и я с радостью зарегистрирую его (ссылаясь на ваш пост здесь, не пытайтесь «украсть» что-либо).

(обновление)

уменьшенный код для воспроизведения:

using System; 
using System.Collections.Generic; 
static class Program { 
    static void Main() { 
     int count = Test.Count; 
    } 

    [Obsolete("Should error", true)] 
    public static List<string> Test { 
     get {throw new NotImplementedException();} 
    } 
} 

Обратите внимание, что моно 2,0 получает это право, так же как # 2.0 компилятора MS C. Это только компилятор MS C# 3.0 (.NET 3.5).

+0

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

4

Я согласен с Marc: это похоже на ошибку компилятора. Интересно, что GMCS (Моно C# компилятор) получает это право:

Test.cs(65,26): warning CS0219: The variable `list' is assigned but its value is never used 
Test.cs(62,38): warning CS0612: `TestApp.BaseClass.Value' is obsolete 
Test.cs(63,38): warning CS0612: `TestApp.BaseClass.ValueArray' is obsolete 
Test.cs(64,38): warning CS0612: `TestApp.BaseClass.ValueList' is obsolete 
Test.cs(65,36): warning CS0612: `TestApp.BaseClass.ValueList' is obsolete 
Compilation succeeded - 5 warning(s) 
+1

Как и MS 2.0; но смешно, как мы оба пытались «gmcs» сначала ... –

+0

Может принимать только один, поэтому я принимаю Marc, как он был первым :) –

18

Это настоящая ошибка. К сожалению, из-за очистки рефакторинга, который пропустил этот случай. Я исправил это для выпуска компилятора C# 4.0, следующего в VS 2010/NDP 4.0, но сейчас нет планов исправить его в Orcas, и, к сожалению, нет никакой работы, о которой я знаю, чтобы справиться с этим.

Ненавижу говорить об этом, но вам нужно будет перейти на NDP 4 csc.exe или VS2010, когда они станут доступны, чтобы исправить эту проблему.

Я думаю о публикации в моем новом новом блоге msdn об этом. Делает хороший анекдотический пример того, как рефакторинг может нарушить ваш код.

Иан Холлидей

компилятора C# SDE
Microsoft

+1

Спасибо, что нашли время, чтобы опубликовать это здесь. Оценил. –

+1

Да, действительно. Еще одна веха для переполнения стека, я думаю :) –

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