Ter constantes públicas é "ruim"?


39

É isto:

public MyClass
{
    public const string SomeString = "SomeValue";
}

pior que isso:

public MyClass
{
    public static string SomeString { get{ return "SomeValue";}}
}

Ambos podem ser referenciados da mesma maneira:

if (someString == MyClass.SomeString)
     ...

O segundo, no entanto, tem a proteção de ser uma propriedade. Mas realmente quanto melhor isso é do que uma const?

Aprendi repetidamente os perigos de ter campos públicos. Então, quando vi algum código usando essas constantes em campos públicos, imediatamente comecei a refatorá-las para propriedades. Mas, no meio do caminho, comecei a me perguntar qual era o benefício de ter as propriedades estáticas sobre as constantes.

Alguma ideia?


1
As constantes públicas usadas dessa maneira são boas. Usar propriedades dessa maneira é um exagero.
Bernard

2
Você já pensou em usar a palavra-chave readonly ? O ReadOnly fornece a sintaxe mais limpa de uma const sem os problemas mencionados em muitas das postagens.
Matt Raffel

Também poderia fazer ... tipo estático público readonly constantName = 0;
Snoop

Respostas:


57

Em C #, é muito ruim por nenhum dos motivos mencionados neste segmento.

As constantes públicas em C # são inseridas em assemblies de referência. Ou seja, se você tiver um SomeOtherClass em um assembly separado referenciando SomeString em MyClass, o CIL gerado para SomeOtherClass conterá uma string "SomeValue" codificada.

Se você reimplementar a dll que contém MyClass, mas não SomeOtherClass, e alterar a const, SomeOtherClass não conterá o que você acha que será - ele conterá o valor original.

Se você é 100% positivo, é uma constante universal como Pi, enlouqueça; caso contrário, pise com cuidado.

Aqui está uma explicação melhor: https://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly


3
@Oded, mas a mesma diferença está entre conste a propriedade somente leitura. consté inserido no assembly de chamada, a propriedade somente leitura não.
svick

1
Isso é algo que eu não sabia. É mais uma evidência de que os campos públicos são ruins. Acho que mesmo o exemplo "seguro" de Pi é uma má idéia (e quando um desenvolvedor deseja mais ou menos dígitos de precisão no Pi? E faz a alteração no assembly sem conhecer esse problema.) Tenho mais de 40 assemblies no meu solução e pude ver isso realmente nos mordendo se não tomarmos cuidado.
Vaccano

2
Essa "cópia" acontece em outras partes do C #? (ie enums)
Vaccano

2
Sim, a cópia acontece. Isso geralmente não é um problema, mas se o seu código usar o valor numérico de um Enum e ele for alterado da maneira descrita nesta pergunta, isso poderá causar problemas.
Vaccano 02/02/2012

1
Essa é uma das principais razões pelas quais o constC # é burro. Precisamos de um melhor suporte para imutáveis ...
KChaloux

22

Mudar um campo para uma propriedade é uma mudança de última hora. Você perde a compatibilidade binária, de origem e de reflexão.

Além do que, além do mais:

  • Há um controle de acesso mais refinado com propriedades. Precisa que seja publicamente disponibilizável, mas na verdade só o deseja com acesso protegido? Não tem problema (pelo menos a partir do C # 2).
  • Deseja entrar no depurador sempre que o valor for alterado? Basta adicionar um ponto de interrupção no setter.
  • Deseja registrar todo o acesso? Basta adicionar o log ao getter.
  • Propriedades são usadas para ligação de dados; campos não são.

http://csharpindepth.com/articles/chapter8/propertiesmatter.aspx

Dito isso, não vejo como as constantes são realmente afetadas por isso (especialmente se você não precisar de nenhum dos recursos acima), a menos que sua API seja alterada de forma que não sejam mais constantes.


11

Os perigos dos campos públicos são o fato de serem mutáveis e a implementação subjacente a eles estar sujeita a alterações.

Quando se trata de constisso, isso normalmente não é um problema (da mesma forma que as enumerações públicas) - a menos que você pense que constisso acabará como mutável e que você precisará de um encapsulamento em torno do acessador em algum momento (diga para registrar quantas vezes ele foi visualizado). você pode mantê-lo em público const.


1

Uma constante são dados. As propriedades implicam a possibilidade de comportamento quando você "olha" para o valor.

O comportamento de agrupamento (ou a possibilidade futura dele) com dados constantes é totalmente errado. Para a maioria dos sistemas, isso realmente não importa, mas pode.

Digamos que o valor seja "PI" e seja usado extensivamente nos cálculos do sistema. Colocá-lo atrás das propriedades forçará os programadores clientes a programar defensivamente. Eles devem atribuir o valor a uma constante duplicada. Se eles não enganarem, a próxima versão da biblioteca poderá ter algum "comportamento" indesejado introduzido atrás da propriedade. O comportamento da propriedade (se estiver em uma biblioteca compilada) é desconhecido. Talvez ele tenha um bom desempenho no teste, mas pode haver código oculto que é executado se uma condição especial for atendida. Esta não é uma otimização pré-madura. Especialmente para um sistema em tempo real, a vida das pessoas depende.

Os programadores clientes podem até perder a segurança de uma constante, pois o idioma pode não permitir que eles atribuam um valor de propriedade à sua constante duplicada.

Além disso, quando os programadores são forçados a atribuir o valor da sua propriedade em sua própria constante, eles efetivamente anulam qualquer comportamento que você espera realizar com sua propriedade.

Dados constantes verdadeiros não precisam ou desejam encapsulamento.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.