Por que C # coleção-propriedades não marcada como obsoleta ao chamar propriedades sobre eles?

StackOverflow https://stackoverflow.com/questions/577132

  •  05-09-2019
  •  | 
  •  

Pergunta

Eu tentei fazer uma propriedade coleção em uma classe como obsoleto para encontrar todas as ocorrências e manter uma lista cada vez menor de coisas para correção no meu aviso-list, devido ao fato de que precisamos para substituir esta propriedade coleção com outra coisa .


Editar : Eu enviei isto através Microsoft Connect, edição # 417159 .

Editar 16.11.2010 : Verificado que esta agora trabalha no compilador C # 4.0, tanto durante a compilação for .NET 3.5 e 4.0. Recebo 4 alertas do código postado, incluindo aquele com o comentário "Not OK?".


No entanto, para minha surpresa, a lista continha apenas algumas ocorrências, muito menos do que eu sabia que havia, e spotchecks me diz que, por algum motivo, o uso da propriedade nem sempre é marcado como obsoleto pelo compilador em a lista de alerta.

Aqui está um exemplo de programa, pronto para compilar no Visual Studio 2008.

Observe as quatro linhas perto do final com a etiqueta # 1- # 4, destes, eu esperaria todos eles para informar que a propriedade usada era obsoleto, mas # 3 não é, e parece que se eu apenas passar para as propriedades de cobrança ou métodos diretamente, o uso da propriedade em si não está sinalizado como obsoleto. Note que # 3 e # 4 está referenciando a mesma propriedade, e # 4 é sinalizado como usar uma propriedade obsoleta, enquanto # 3 não é. Testes mostra que, se, na expressão, para acessar propriedades ou métodos da coleção a propriedade retorna, o compilador não reclamar.

Este é um bug, ou esta é uma "jóia escondida" do compilador C # eu não estava ciente de?

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
        }
    }
}
Foi útil?

Solução

Hmm ... parece um bug do compilador para mim! Ele falha o seguinte (ECMA 334v4):

24.4.3 O atributo Obsoleto O atributo obsoleto é usado para marcar tipos e membros de tipos que deve deixará de ser usado. Se um programa usa uma tipo ou membro que está decorado com o atributo obsoleto, então o compilador emitirá um aviso ou erro, a fim de alertar o desenvolvedor, de modo que o código incorreto pode ser corrigido. Especificamente, o compilador emitirá um aviso se nenhum parâmetro de erro é fornecido, ou se o parâmetro de erro é fornecido e tem o valor falso. o compilador emitirá um tempo de compilação erro se o parâmetro de erro é especificada e tem o valor verdadeiro.

Em particular, quando marcou verdadeira deve emitir um erro, e isso não acontece. Bom encontrar! Você poderia denunciá-la em "Connect", ou se você não quer que a dor de criar um login, deixe-me saber e eu vou alegremente registrá-lo (referenciar a sua post aqui, nenhuma tentativa de "roubar" alguma coisa) <. / p>

(atualização)

código Reduzido a reproduzir:

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

Note que mono 2,0 acerta, assim como o MS C # 2.0 do compilador. É apenas o MS C # 3.0 (.NET 3.5) compilador que é quebrado.

Outras dicas

Este é um erro genuíno. Infelizmente, devido a uma limpeza refatoração que perdeu neste caso. Eu reparei isso para o C # 4.0 versão do compilador chegando em VS 2010 / NDP 4.0, mas não há planos para corrigi-lo agora em Orcas e, infelizmente, não há nenhum trabalho ao redor eu conheço para lidar com isso.

Eu odeio dizer isso, mas você terá que atualizar para o NDP 4 csc.exe ou VS2010 quando eles se tornam disponíveis para corrigir esse problema.

Estou pensando em postar uma entrada no meu novo blog MSDN fresco sobre isso. Faz um bom exemplo anedótica de como refatoração pode quebrar seu código.

Ian Halliday

C # Compiler SDE
Microsoft

Eu concordo com Marc: parece que um erro do compilador. Curiosamente, gmcs (o Mono C # compilador) acerta:

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)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top