2009-02-23 10 views
13

Ho provato a contrassegnare una proprietà della raccolta su una classe come Obsoleta per trovare tutte le occorrenze e mantenere un elenco di restringimenti delle cose da correggere nella mia lista di avvisi, a causa del fatto che abbiamo bisogno di sostituire questa proprietà di raccolta con qualcos'altro.Perché le proprietà della raccolta C# non vengono contrassegnate come obsolete quando si richiamano le proprietà su di esse?


Edit: Ho presentato questo attraverso Microsoft Connect, issue #417159.

Modifica 16.11.2010: verificato che questo ora funziona nel compilatore C# 4.0, sia durante la compilazione per .NET 3.5 e 4.0. Ricevo 4 avvisi nel codice pubblicato, incluso quello con il commento "Non è OK?".


Tuttavia, con mia grande sorpresa, la lista conteneva solo poche occorrenze, molto meno di quanto sapevo che c'erano, e spotchecks mi dice che per qualche motivo, l'utilizzo della proprietà non è sempre contrassegnato come obsoleto dal compilatore nella lista di avvisi.

Ecco un esempio di programma, pronti per compilare in Visual Studio 2008.

Nota le quattro linee verso la fine con i tag # 1- # 4, di questi, mi aspetto tutti loro di riferire che la la proprietà utilizzata era obsoleta, ma # 3 non lo è, e sembra che se si passa direttamente alle proprietà o ai metodi della raccolta direttamente, l'utilizzo della proprietà stessa non viene contrassegnato come obsoleto. Nota che il n. 3 e il n. 4 fanno riferimento alla stessa proprietà e il n. 4 è contrassegnato come se utilizzasse una proprietà obsoleta, mentre il n. 3 non lo è. I test mostrano che se, nell'espressione, accedo alle proprietà o ai metodi della raccolta restituiti dalla proprietà, il compilatore non si lamenta.

Si tratta di un bug o di una "gemma nascosta" del compilatore C# di cui non ero a conoscenza?

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

Ho segnato il vostro "connect" come convalidato e dato un voto ... –

+0

btw, non vorrei anticipare una correzione prima di C# 4.0 ; il codice sarebbe compilato in 2.0? Forse prova il compilatore 2.0 ... –

+0

nah, ce la faremo, l'ho scoperto solo per errore quando ho provato ad usare ObsoleteAttribute come un modo veloce per ottenere una lista "da fare" per le cose da sistemare prima di procedere con il refactoring. –

risposta

14

Hmm ... sembra un errore del compilatore per me! Non riesce il seguente (ECMA 334v4):

24.4.3 L'attributo obsoleto L'attributo obsoleto viene utilizzato per contrassegnare tipi e membri di tipi che dovrebbe non più utilizzabili. Se un programma utilizza un tipo o di un membro che è decorato con l'attributo obsoleto, quindi il compilatore emette un avvertimento o errore per allertare lo sviluppatore, modo che il codice incriminato può essere risolto. In particolare, il compilatore deve emettere un avviso se nessun parametro di errore è fornito, o se il parametro di errore è fornito e ha il valore falso. Il compilatore deve emettere un errore in fase di compilazione se il parametro di errore è specificato e ha il valore true.

In particolare, se contrassegnato true, dovrebbe generare un errore e non lo è. Buona scoperta! Puoi segnalarlo su "connect", o se non vuoi il dolore di creare un login, fammelo sapere e lo registrerò felicemente (riferendosi al tuo post qui, nessun tentativo di "rubare" nulla).

(aggiornamento)

codice ridotto per riprodurre:

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();} 
    } 
} 

Nota che mono 2.0 ottiene di destra, così come la # 2.0 compilatore MS C. È solo il compilatore MS C# 3.0 (.NET 3.5) che è danneggiato.

+0

Ok, bene, questo conferma i miei sospetti, ho modificato la mia domanda e pubblicato il link al problema di connessione. –

4

Sono d'accordo con Marc: sembra un bug del compilatore. È interessante notare che, GMCs (Mono compilatore C#) ottiene il diritto:

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

Così come MS 2.0; ma è divertente come entrambi abbiamo provato "gmcs" per primo ... –

+0

Posso accettarne solo uno, quindi accetto Marc's come prima :) –

18

Si tratta di un vero e proprio bug. Sfortunatamente a causa di una pulizia del refactoring che ha mancato questo caso. Ho risolto questo problema per il rilascio del compilatore C# 4.0 in arrivo su VS 2010/NDP 4.0 ma non ci sono piani per risolverlo ora in Orcas e sfortunatamente non c'è alcun lavoro in giro che io sappia trattare con questo.

Odio dirlo ma sarà necessario eseguire l'aggiornamento a NSS 4 csc.exe o VS2010 quando saranno disponibili per risolvere questo problema.

Sto pensando di pubblicare una voce sul mio nuovo blog msdn su questo. Fa un buon esempio aneddotico di come il refactoring può infrangere il tuo codice.

Ian Halliday

compilatore C# SDE
Microsoft

+1

Grazie per aver trovato il tempo di postare qui. Apprezzato. –

+1

Sì, certo. Un'altra pietra miliare per Stack Overflow, penso :) –

Problemi correlati