A const pública é ruim?
A const pública é ruim?
Declarar um número ou string como const pública é considerado uma prática ruim? Vamos dar uma olhada no que uma variável const significa em primeiro lugar.
Vamos pegar a definição da referência oficial do C#:
"Você usa a palavra-chave const para declarar um campo constante ou uma constante local. Campos constantes e locais não são variáveis e não podem ser modificados. Constantes podem ser números, valores booleanos, strings ou uma referência nula. Não crie uma constante para representar informações que você espera mudar a qualquer momento."
Agora para começar esta parte é importante "Campos constantes e locais não são variáveis ...". Isso é essencial. Vamos dar uma olhada no seguinte trecho de código:
using System;
Console.Write(MyClass.MyConstantString);
public class MyClass
{
public const string MyConstantString = "Hello";
}
O compilador reduzirá esse termo para o seguinte código Fonte em sharplab.io
internal class Program
{
private static void <Main>$(string[] args)
{
Console.Write("Hello");
}
}
public class MyClass
{
public const string MyConstantString = "Hello";
}
Hupps. Onde está a referência a MyClass.MyConstantString no Console.Write? Exatamente não existindo mais. campos const e locais de fato não são variáveis e, portanto, serão "substituídos" pelo compilador em tempo de compilação em todos os lugares em que a constante for usada. Isso pode trazer um grande problema:
Assemblies de referência
Imagine que você tem a seguinte classe no Assembly A:
public class MyClassInAssemblyA
{
public const string MyConstantString = "Hello";
}
E um usuário da classe no Assembly B:
public class MyClassInAssemblyA
{
public void WriteSomething() => Console.WriteLine(MyClassInAssemblyA.MyConstantString);
}
Se compilarmos isso e chamarmos WriteSomething, o console imprimirá "Hello". Agora vamos mais longe e mudamos MyConstantString de "Olá" para "mundo". Nós reimplantamos o Assembly A, mas não o Assembly B, qual será a saída de WriteSomething? Ainda "Olá". Por quê? Porque, como mostrado anteriormente, a string const é codificada no assembly. Isso significa que para refletir as alterações mais recentes, você também precisa recompilar o Assembly B. Agora, isso não é muito útil quando você desenvolve software onde tudo está sob seu controle, mas pode ser complicado, por exemplo, se você desenvolver plugins, onde o chamador não ser recompilado automaticamente.
Como consertar isso
A correção mais fácil é usar um campo estático somente leitura. Então, tomando nosso exemplo desde o início, refatoramos isso para um campo estático somente leitura:
using System;
Console.Write(MyClass.MyConstantString);
public class MyClass
{
public static readonly string MyConstantString = "Hello";
}
E o código resultante ficará assim:
internal class Program
{
private static void <Main>$(string[] args)
{
Console.Write(MyClass.MyConstantString);
}
}
public class MyClass
{
public static readonly string MyConstantString = "Hello";
}
Podemos ver claramente que o Console.Write agora usa a referência "real" em vez da string codificada. Ou seja, se alterarmos MyClass.MyConstantString, ele também será refletido automaticamente.
?? A mudança de const pública para readonly estática pública é considerada uma alteração importante. Você perde a compatibilidade binária, de origem e de reflexão. Então, se você fizer versionamento semântico, terá que aumentar o número principal. Esteja ciente disso.
Além disso, você não pode usar campos/variáveis estáticos somente leitura nos seguintes cenários:
- Argumentos de atributo
- Alternar declarações
- Declarações de parâmetros opcionais
A const pública é ruim então?
Como sempre: Depende. Principalmente no fato de você ter controle total sobre todo o fluxo e código-fonte, se você provavelmente não tiver. Além disso, se você está 100% certo de que seu const nunca mudará, vá em frente. Algo como public const int Zero = 0 ou Pi. Caso contrário, seja muito cauteloso se você quiser usar const público. O mesmo se aplica para const protegido. Tudo o que é visível fora da sua montagem.
É claro que const privado ou const interno são seguros a esse respeito.