Estou estudando C # e me pergunto qual ToString
pode ser o objetivo e a vantagem de substituir , conforme mostrado no exemplo abaixo.
Isso poderia ser feito de uma maneira mais simples, usando um método comum sem a substituição?
public string GetToStringItemsHeadings
{
get { return string.Format("{0,-20} {1, -20}", "Office Email", "Private Email"); }
}
public override string ToString()
{
string strOut = string.Format("{0,-20} {1, -20}", m_work, m_personal);
return strOut;
}
c#
overriding
3D-kreativ
fonte
fonte
Console.WriteLine(obj.GetToStringItemsHeadings); Console.WriteLine(obj);
ou semelhante.GetToString
no nome da propriedade ... Então você obteria, por exemploConsole.WriteLine(obj.ItemHeadings)
Respostas:
Você precisa substituir
ToString
? Não.Você pode obter uma representação de string de seu objeto de outra maneira? Sim.
Mas, ao usar,
ToString
você está usando um método comum a todos os objetos e, portanto, outras classes sabem sobre esse método. Por exemplo, sempre que o .NET framework deseja converter um objeto em uma representação de string,ToString
é um candidato principal (existem outros, se você quiser fornecer opções de formatação mais elaboradas).Concretamente,
iria invocar
yourObject.ToString()
.fonte
@yourObject
e<%=yourObject%>
será "ToString-ed".ToString
não deve realmente alterar o estado de um objeto. Mas não foi isso que eu defendi.ToString
está destinado a ser substituído. Período. Colocar uma advertência nesta declaração não é produtivo. Se você fizer isso errado - sua própria culpa. Na verdade, seu aluno violou o ponto 4 da lista oficial de diretrizes para anulaçãoToString
que foi postada na resposta de David Anderson.Vou apenas dar a você a resposta direto do Framework Design Guidelines da .NET Development Series.
EVITE lançar exceções de
ToString
CONSIDER retornando uma string exclusiva associada à instância.
CONSIDERE ter a saída de
ToString
ser uma entrada válida para qualquer método de análise neste tipo.ASSEGURE- SE de que
ToString
não haja efeitos colaterais observáveis.DO relatório de informação sensível à segurança através de uma substituição de
ToString
apenas após exigindo uma permissão apropriada. Se a solicitação de permissão falhar, retorne uma string excluindo informações confidenciais de segurança.O
Object.ToString
método deve ser usado para fins gerais de exibição e depuração. A implementação padrão simplesmente fornece o nome do tipo de objeto. A implementação padrão não é muito útil e é recomendado que o método seja substituído.DO substituição
ToString
sempre que uma string legível interessante pode ser devolvido. A implementação padrão não é muito útil e uma implementação customizada quase sempre pode fornecer mais valor.Prefira um nome amigável em vez de um ID exclusivo, mas não legível.
Também vale a pena mencionar, já que Chris Sells também explica nas diretrizes, que
ToString
geralmente é perigoso para interfaces de usuário. Geralmente, minha regra prática é expor uma propriedade que seria usada para vincular informações à IU e deixar aToString
substituição para exibir informações de diagnóstico para o desenvolvedor. Você também pode decorar seu tipo comDebuggerDisplayAttribute
.DO tentar manter a cadeia devolvida a partir
ToString
curto. O depurador usaToString
para obter uma representação textual de um objeto a ser mostrado ao desenvolvedor. Se a string for mais longa do que o depurador pode exibir, a experiência de depuração é prejudicada.FAÇA a formatação da string com base na cultura de thread atual ao retornar informações dependentes da cultura.
DO fornecer sobrecarga
ToString(string format)
, ou implementarIFormattable
, se o retorno seqüência deToString
é sensível à cultura ou existem várias maneiras de formatar a string. Por exemplo,DateTime
fornece a sobrecarga e implementosIFormattable
.NÃO retorne uma string vazia ou nula de
ToString
Juro por essas diretrizes e você deve fazer isso. Eu não posso dizer como meu código melhorou apenas por esta diretriz para
ToString
. A mesma coisa vale para coisas comoIEquatable(Of T)
eIComparable(Of T)
. Essas coisas tornam seu código muito funcional e você não se arrependerá de perder tempo para implementá-lo.Pessoalmente, nunca usei
ToString
muito para interfaces de usuário, sempre expus uma propriedade ou método de algum tipo. Na maioria das vezes, você deve usarToString
para fins de depuração e desenvolvedor. Use-o para exibir informações importantes de diagnóstico.fonte
A substituição
ToString()
permite que você forneça uma representação de string legível por humanos de uma classe.Isso significa que a saída pode revelar informações úteis sobre sua classe. Por exemplo, se você tivesse uma classe Person, você poderia escolher ter como
ToString()
saída o id da pessoa, seu nome, sobrenome, etc. Isso é extremamente útil ao depurar ou registrar.Com relação ao seu exemplo - é difícil dizer se sua substituição é útil sem saber o que esta classe é - mas a implementação em si está ok.
fonte
É sempre apropriado, mas considere cuidadosamente as intenções por trás do que você está exibindo
Uma pergunta melhor seria fazer:
ToString () é a janela para o estado de um objeto. Ênfase no estado como um requisito. Linguagens fortemente OOP como Java / C # abusam do modelo OOP encapsulando tudo em uma classe. Imagine que você está codificando em uma linguagem que não segue o modelo OOP forte; considere se você usaria uma classe ou uma função. Se você for usá-lo como uma função (ou seja, verbo, ação) e o estado interno for mantido apenas temporariamente entre a entrada / saída, ToString () não adicionará valor.
Como outros mencionaram, é importante considerar o que você produz com ToString () porque ele pode ser usado pelo depurador ou outros sistemas.
Gosto de imaginar o método ToString como o parâmetro --help de um objeto. Deve ser curto, legível, óbvio e fácil de exibir. Deve mostrar o que o objeto não é o que faz . Com tudo isso em mente, vamos considerar ...
Caso de uso - analisando um pacote TCP:
Não é uma captura de rede apenas no nível do aplicativo, mas algo com mais carne, como uma captura pcap.
Você deseja sobrecarregar ToString () apenas para a camada TCP para que possa imprimir dados no console. O que isso incluiria? Você poderia enlouquecer e analisar todos os detalhes do TCP (ou seja, o TCP é complexo) ...
Que inclui:
Mas você gostaria de receber todo esse lixo se estivesse chamando TCP.ToString () em 100 pacotes? Claro que não, seria sobrecarga de informação. A escolha fácil e óbvia também é a mais sensata ...
Exponha o que as pessoas esperariam ver:
Eu prefiro uma saída sensata que seja fácil para humanos analisar, mas YMMV .
Nada complexo, a saída não é para ser analisada por máquinas (ou seja, a menos que as pessoas estejam abusando do seu código), a finalidade pretendida é para legibilidade humana.
Mas e todo o resto daquela informação suculenta de que falei antes, não é útil também? Vou chegar lá, mas primeiro ...
ToString () um dos métodos mais valiosos e subutilizados de todos os tempos
Por dois motivos:
Razão 1 - Não abuse da utilidade de ToString ():
Muitas pessoas usam ToString () para obter uma representação de string simples de um objeto. O manual C # ainda afirma:
Exibição, sem processamento adicional. Isso não significa, pegue minha bela representação de string do pacote TCP acima e puxe a porta de origem usando um regex :: cringe ::.
A maneira certa de fazer as coisas é chamar ToString () diretamente na propriedade SourcePort (que BTW é um ushort, então ToString () já deve estar disponível).
Se você precisa de algo mais robusto para empacotar o estado de um objeto complexo para análise de máquina, será melhor usar uma estratégia de serialização estruturada.
Felizmente, essas estratégias são muito comuns:
Nota: A menos que você esteja usando PHP porque, herp-derp, há uma função para isso :: snicker ::
Razão 2 - ToString () não é suficiente:
Ainda estou para ver uma linguagem que implemente isso no núcleo, mas tenho visto e usado variações dessa abordagem na selva.
Algumas das quais incluem:
Basicamente, essa bagunça cabeluda do estado de um pacote TCP deve ser descrita para facilitar a leitura humana. Para evitar 'bater em um cavalo morto' falando sobre TCP, irei 'apontar o dedo' para o caso nº 1 onde eu acho que ToString () e ToVerboseString () são subutilizados ...
Caso de uso - Arrays:
Se você usa principalmente um idioma, provavelmente está confortável com a abordagem desse idioma. Para pessoas como eu, que alternam entre idiomas diferentes, o número de abordagens variadas pode ser irritante.
Ou seja, o número de vezes que isso me irritou é maior do que a soma de todos os dedos de todos os deuses hindus combinados.
Há vários casos em que línguas uso comum hacks e um poucos que obter -lo direito . Alguns exigem a reinvenção da roda, alguns fazem um despejo raso, outros fazem um despejo profundo, nenhum deles funciona da maneira que eu gostaria ...
O que estou pedindo é uma abordagem muito simples:
Onde x é o número de itens na primeira dimensão ey é o número de itens na segunda dimensão ou algum valor que indica que a 2ª dimensão é denteada (intervalo mínimo / máximo talvez?).
E:
Espero que isso lance alguma luz sobre um tópico que me incomoda há muito tempo. No mínimo, espalhei uma pequena isca de troll para que os PHPers votassem negativamente nessa resposta.
fonte
ToString()
for para depuração, por que é a única maneira de extrair todo o texto de um StringBuilder - uma função importante?É sobre boas práticas tanto quanto qualquer outra coisa, na verdade.
ToString()
é usado em muitos lugares para retornar uma representação de string de um objeto, geralmente para consumo por um ser humano. Freqüentemente, essa mesma string pode ser usada para reidratar o objeto (pense emint
ouDateTime
por exemplo), mas isso nem sempre é dado (uma árvore, por exemplo, pode ter uma representação de string útil que simplesmente exibe um Count, mas claramente você não pode usar isso para reconstruí-lo).Em particular, o depurador usará isso para exibir a variável nas janelas de observação, janelas imediatas, etc., portanto,
ToString
é realmente inestimável para depuração.Em geral, também, esse tipo geralmente terá um membro explícito que também retorna uma string. Por exemplo, um par Lat / Long pode ter
ToDecimalDegrees
quais retornos,"-10, 50"
por exemplo, mas também pode terToDegreesMinutesSeconds
, já que esse é outro formato para um par Lat / Long. Esse mesmo tipo também pode substituirToString
por um daqueles para fornecer um 'padrão' para coisas como depuração, ou mesmo potencialmente para coisas como renderização de páginas da web (por exemplo, a@
construção no Razor escreve oToString()
resultado de uma expressão não string para o fluxo de saída).fonte
object.ToString()
converte um objeto em sua representação de string. Se você deseja alterar o que é retornado quando um usuário chamaToString()
uma classe que você criou, você precisa substituirToString()
essa classe.fonte
Embora eu ache que as informações mais úteis já foram fornecidas, devo acrescentar meus dois centavos:
ToString()
deve ser substituído. Sua implementação padrão retorna o nome do tipo que, embora possa ser útil às vezes (particularmente ao trabalhar com muitos objetos), não é suficiente na grande maioria das vezes.Lembre-se de que, para fins de depuração, você pode confiar
DebuggerDisplayAttribute
. Você pode ler mais sobre isso aqui .Como regra, em POCOs você sempre pode substituir
ToString()
. POCOs são uma representação estruturada de dados, que geralmente podem se tornar uma string.Projete ToString para ser uma representação textual de seu objeto. Talvez seus principais campos e dados, talvez uma descrição de quantos itens estão na coleção, etc.
Sempre tente encaixar essa string em uma única linha e tenha apenas as informações essenciais. Se você tiver uma
Person
classe com as propriedades Nome, Endereço, Número etc., retorne apenas os dados principais (Nomeie algum número de ID).Tenha cuidado para não substituir uma boa implementação de
ToString()
. Algumas classes do framework já implementamToString()
. Substituir essa implementação padrão é uma coisa ruim: as pessoas esperarão um certo resultadoToString()
e obterão outro.Não tenha medo de usar
ToString()
. A única coisa com que eu teria cuidado é retornar informações confidenciais. Fora isso, o risco é mínimo. Claro, como alguns apontaram, outras classes usarão seu ToString sempre que buscar informações. Mas, diabos, quando retornar o nome do tipo será considerado melhor do que obter algumas informações reais?fonte
Se você não substituir
ToString
, obterá a implementação de suas classes base que, pois,Object
é apenas o nome de tipo abreviado da classe.Se você quiser alguma outra implementação mais significativa ou útil do
ToString
, substitua-o.Isso pode ser útil ao usar uma lista do seu tipo como a fonte de dados para a,
ListBox
poisToString
será exibida automaticamente.Outra situação ocorre quando você deseja passar seu tipo para o
String.Format
qual invocaToString
para obter uma representação de seu tipo.fonte
Algo que ninguém mais mencionou ainda: ao substituir
ToString()
, você também pode considerar a implementaçãoIFormattable
para fazer o seguinte:O que pode ser útil.
fonte
IFormattible
interface.System.Object
terá umToString()
método substituível , mas você está certo que o método do formatador não deve seroverride
e deve realmente fazer referência àIFormattible
interface para conformidade completa.IFormattable
leva umIFormatProvider
parâmetro. Obrigado por editar sua postagem.Um benefício de substituir ToString () é o suporte a ferramentas do Resharper: Alt + Ins -> "Formatando membros" e grava o ToString () para você.
fonte
Em alguns casos, torna mais fácil ler os valores das classes personalizadas na janela de observação do depurador. Se eu sei exatamente o que quero ver na janela de observação, quando substituo ToString com essa informação, então eu vejo.
fonte
Ao definir structs (efetivamente primitivos do usuário), acho que é uma boa prática ter métodos,
ToString
eParse
e correspondentesTryParse
, especialmente para serialização XML. Neste caso, você converterá todo o estado em uma string, para que possa ser lido posteriormente.As classes, entretanto, são estruturas mais compostas que geralmente são muito complexas para usar
ToString
eParse
. SeusToString
métodos, em vez de salvar todo o estado, podem ser uma descrição simples que ajuda a identificar seu estado, como um identificador único como um nome ou ID, ou talvez uma quantidade para uma lista.Além disso, como Robbie disse, substituir
ToString
permite que você chameToString
uma referência tão básica quanto o tipoobject
.fonte
Você pode usar isso quando tiver um objeto sem significado intuitivo de representação de string, como pessoa. Então, se você precisa, por exemplo, imprimir esta pessoa, você pode usar esta substituição para preparar seu formato.
fonte
O
Object.ToString
método deve ser usado apenas para fins de depuração. A implementação padrão mostra o nome do tipo de objeto que não é muito útil. Considere substituir esse método para fornecer melhores informações para diagnóstico e depuração. Considere que as infraestruturas de registro geralmente também usam o método ToString e, portanto, você encontrará esses fragmentos de texto em seus arquivos de registro.Não retorne recursos de texto localizados dentro do
Object.ToString
método. O motivo é que o método ToString deve sempre retornar algo que o desenvolvedor possa entender. O desenvolvedor pode não falar todos os idiomas suportados pelo aplicativo.Implemente a
IFormattable
interface quando desejar retornar um texto localizado amigável. Esta interface define uma sobrecarga ToString com os parâmetrosformat
eformatProvider
. O formatProvider ajuda você a formatar o texto de uma maneira que leve em consideração a cultura.Veja também: Object.ToString e IFormattable
fonte
Mais simples depende de como sua propriedade será usada. Se você só precisa formatar a string uma vez, não faz muito sentido substituí-la.
No entanto, parece que você está substituindo o método ToString para não retornar os dados de string normais para sua propriedade, mas para executar um padrão de formatação padrão. Já que você está usando string.format com preenchimento.
Como você disse que está aprendendo, o exercício parece também atingir os princípios básicos da programação orientada a objetos relacionados ao encapsulamento e à reutilização de código.
O string.format recebendo os argumentos que você definiu para preenchimento garante que a propriedade será formatada da mesma maneira todas as vezes para qualquer código que a chame. Da mesma forma, daqui para frente, você só precisa alterá-lo em um lugar, em vez de muitos.
Ótima pergunta e também ótimas respostas!
fonte
Acho útil substituir o método ToString nas classes de entidade, pois ajuda a identificar rapidamente os problemas no teste, especialmente quando uma asserção falha, o console de teste invoca o método ToString no objeto.
Mas, de acordo com o que foi dito antes, é para dar uma representação legível humana do objeto em questão.
fonte
Estou satisfeito com as Diretrizes da Estrutura mencionadas em outras respostas. No entanto, gostaria de enfatizar os propósitos de exibição e depuração.
Seja cuidadoso sobre como você usa
ToString
em seu código. Seu código não deve depender da representação de string de um objeto. Em caso afirmativo, você deve fornecer os respectivosParse
métodos.Uma vez que
ToString
pode ser usado em qualquer lugar, pode ser um problema de manutenção se você quiser alterar a representação de string de um objeto posteriormente. Você não pode simplesmente examinar a hierarquia de chamadas neste caso para estudar se algum código será quebrado.fonte