Estou lendo Effective C # de Bill Wagner. No Item 14 - Minimize Duplicate Initialization Logic , ele mostra o seguinte exemplo de uso do novo recurso de parâmetros opcionais em um construtor:
public MyClass(int initialCount = 0, string name = "")
Observe que ele usou em ""
vez de string.Empty
.
Ele comenta:
Você notará [em um exemplo acima] que o segundo construtor especificou "" como o valor padrão no parâmetro de nome , em vez do mais usual
string.Empty
. Isso porquestring.Empty
não é uma constante de tempo de compilação. É uma propriedade estática definida na classe string. Como não é uma constante de compilação, você não pode usá-la como o valor padrão de um parâmetro.
Se não podemos usar a string.Empty
estática em todas as situações, isso não anula o propósito dela? Pensei em usá-lo para ter certeza de que temos um meio independente do sistema de se referir à string vazia. Meu entendimento está errado? Obrigado.
ATUALIZAÇÃO
Apenas um comentário de acompanhamento. De acordo com o MSDN:
Cada parâmetro opcional possui um valor padrão como parte de sua definição. Se nenhum argumento for enviado para esse parâmetro, o valor padrão será usado. Os valores padrão devem ser constantes.
Então não podemos usar System.Environment.NewLine
nenhum dos dois, ou usar objetos recém-instanciados como valores padrão. Eu não usei o VS2010 ainda, e isso é decepcionante!
fonte
Respostas:
A partir do compilador C # 2.0, há muito pouco sentido para
String.Empty
qualquer coisa e, na verdade, em muitos casos é uma pessimização, já que o compilador pode embutir algumas referências a,""
mas não pode fazer o mesmo comString.Empty
.No C # 1.1, era útil evitar a criação de muitos objetos independentes, todos contendo a string vazia, mas esses dias acabaram.
""
funciona muito bem.fonte
Não há nada que o impeça de definir sua própria constante para a string vazia se você realmente quiser usá-la como um valor de parâmetro opcional:
[Como um aparte, um motivo para preferir
String.Empty
sobre""
, em geral, que não tenha sido mencionado em outras respostas, é que existem vários caracteres Unicode (marceneiro de largura zero, etc.) que são eficazmente invisível a olho nu. Portanto, algo que parece""
não é necessariamente a string vazia, enquanto comString.Empty
você sabe exatamente o que está usando. Reconheço que esta não é uma fonte comum de bugs, mas é possível.]fonte
Da pergunta original:
De que forma a string vazia pode variar de sistema para sistema? É sempre uma string sem caracteres! Eu ficaria muito assustado se encontrasse uma implementação onde
string.Empty == ""
retornasse falso :) Isso não é o mesmo que algo parecidoEnvironment.NewLine
.Da postagem de recompensa do Counter Terrorist:
Bem, isso certamente não vai acontecer.
Embora eu pessoalmente também tivesse gostado de um mecanismo de padronização muito diferente, a forma como os parâmetros opcionais funcionam tem sido no .NET desde o início - e isso sempre significa incorporar uma constante nos metadados, de modo que o código de chamada possa copiar essa constante na chamada site se nenhum argumento correspondente for fornecido.
Com
string.Empty
ele é realmente inútil - usar""
fará o que você quiser; é tão doloroso usar o literal de string? (Eu uso o literal em todos os lugares - nunca usostring.Empty
- mas esse é um argumento diferente.)Isso é o que me surpreende nesta questão - a reclamação gira em torno de algo que não causa um problema real. É mais importante nos casos em que você deseja que o padrão seja calculado no tempo de execução porque ele pode realmente variar. Por exemplo, eu poderia imaginar casos em que você deseja chamar um método com um
DateTime
parâmetro e defini-lo como "a hora atual" como padrão. No momento, a única solução vagamente elegante que conheço para isso é:... mas isso nem sempre é apropriado.
Em conclusão:
string.Empty
é inútil de qualquer maneirafonte
Environment.Newline
.. A única coisa que falta em seu exemplo seria uma verificação na variável para nulo e lançar uma exceção de volta para o desenvolvedor dizendo a ele que, embora seja anulável, é Não aceito.if(dateTime == null){ throw new ArgumentException("The dateTime parameter must be set. Nullable type used for device independent variable set.");}
ou algo assim. Mas eu realmente gosto disso! Alguma outra advertência para fazer do seu jeito?Nunca uso string. Vazio, não consigo ver o sentido disso. Talvez facilite para as pessoas que são realmente novas em programação, mas duvido que seja útil até para isso.
fonte
""
e" "
, mas não posso dizer que" "
seja tão comum.Acho que a ideia por trás do string.Empty é que aumenta a legibilidade. Não é como uma nova linha, onde há qualquer diferença entre como ela é representada em diferentes plataformas. É uma pena que não pode ser usado em um parâmetro padrão. No entanto, isso não causará problemas se você migrar entre o Windows e algo como Mono no Linux.
fonte
String.Empty
mais legível. . . pessoalmente, porém, acho que é um pouco maluco.""
é provavelmente a string mais comum que existe e todo mundo já a viu um bilhão de vezes, então como é ilegível?String.Empty
é tão útil quanto se houvesse umInt32.Zero
.Como um FYI, parece que a mesma restrição é imposta aos valores passados para os construtores de atributos - eles devem ser constantes. Uma vez que string.empty é definido como:
em vez de uma constante real, ela não pode ser usada.
fonte
Eu uso
string.Empty
puramente para facilitar a leitura.Se outra pessoa precisar ler / alterar meu código mais tarde, eles sabem que eu pretendia verificar ou definir algo como uma string vazia. Usar apenas
""
às vezes pode causar bugs e confusão, porque posso simplesmente ter esquecido de colocar a string que queria lá.Por exemplo:
vs
A primeira
if
declaração parece muito mais deliberada e legível para mim. Como isso é apenas uma preferência, eu realmente não vejo problema em ter que usar em""
vez destring.Empty
.fonte
Talvez a melhor solução para este problema seja uma sobrecarga deste método, desta forma:
fonte