Estoy estudiando C # y me pregunto cuál ToString
podría ser el punto y el beneficio de anular , como se muestra en el siguiente ejemplo.
¿Podría hacerse esto de una manera más simple, usando un método común sin la anulación?
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
fuente
fuente
Console.WriteLine(obj.GetToStringItemsHeadings); Console.WriteLine(obj);
o similar.GetToString
el nombre de la propiedad ... Entonces obtendría, por ejemploConsole.WriteLine(obj.ItemHeadings)
Respuestas:
¿Necesitas anular
ToString
? No.¿Puede obtener una representación de cadena de su objeto de otra manera? Si.
Pero al usar,
ToString
estás usando un método que es común a todos los objetos y, por lo tanto, otras clases conocen este método. Por ejemplo, siempre que el marco .NET desee convertir un objeto en una representación de cadena,ToString
es un candidato principal (hay otros, si desea proporcionar opciones de formato más elaboradas).Concretamente,
invocaría
yourObject.ToString()
.fuente
@yourObject
y<%=yourObject%>
van a ser "ToString-ed".ToString
en realidad, no debería cambiar el estado de un objeto. Pero esto no es lo que defendí.ToString
está destinado a ser anulado. Período. Hacer una advertencia sobre esta afirmación no es productivo. Si lo hace mal, es culpa suya. De hecho, su estudiante violó el punto 4 de la lista oficial de pautas para anularToString
que se publicó en la respuesta de David Anderson.Solo le daré la respuesta directamente de las Pautas de diseño de marco de la Serie de desarrollo de .NET.
EVITE lanzar excepciones de
ToString
CONSIDERE devolver una cadena única asociada con la instancia.
CONSIDERE que la salida
ToString
sea una entrada válida para cualquier método de análisis de este tipo.ASEGÚRESE de que
ToString
no tenga efectos secundarios observables.DEBE reportar información sensible a la seguridad a través de una anulación de
ToString
solo después de exigir un permiso apropiado. Si la solicitud de permiso falla, devuelva una cadena que excluya la información sensible a la seguridad.El
Object.ToString
método está destinado a ser utilizado con fines generales de visualización y depuración. La implementación predeterminada simplemente proporciona el nombre del tipo de objeto. La implementación predeterminada no es muy útil y se recomienda que se anule el método.SÍ anule
ToString
siempre que se pueda devolver una cadena interesante legible por humanos. La implementación predeterminada no es muy útil y una implementación personalizada casi siempre puede proporcionar más valor.DO prefieren un nombre más de un ID único legible, pero no.
También vale la pena mencionarlo como Chris Sells también explica en las pautas que a
ToString
menudo es peligroso para las interfaces de usuario. En general, mi regla general es exponer una propiedad que se usaría para vincular información a la interfaz de usuario y dejar laToString
anulación para mostrar información de diagnóstico al desarrollador. También puede decorar su tipoDebuggerDisplayAttribute
también.DO tratar de mantener la cadena de regresar de
ToString
corto. El depurador utilizaToString
para obtener una representación textual de un objeto que se mostrará al desarrollador. Si la cadena es más larga de lo que puede mostrar el depurador, la experiencia de depuración se ve obstaculizada.HAGA formato de cadena según la cultura del hilo actual al devolver información dependiente de la cultura.
DEBE proporcionar sobrecarga
ToString(string format)
, o implementarIFormattable
, si la cadena devueltaToString
es sensible a la cultura o si hay varias formas de formatear la cadena. Por ejemplo,DateTime
proporciona la sobrecarga y los implementosIFormattable
.NO devuelva una cadena vacía o nula de
ToString
Juro por estas pautas, y debería hacerlo. No puedo decirles cómo ha mejorado mi código solo con esta guía para
ToString
. Lo mismo ocurre con cosas comoIEquatable(Of T)
yIComparable(Of T)
. Estas cosas hacen que su código sea muy funcional, y no se arrepentirá de tomarse el tiempo adicional para implementarlo.Personalmente, nunca he usado
ToString
mucho para las interfaces de usuario, siempre he expuesto una propiedad o método de algún tipo. La mayor parte del tiempo se debe utilizarToString
para fines de depuración y desarrollo. Úselo para mostrar información de diagnóstico importante.fuente
La anulación le
ToString()
permite proporcionar una representación de cadena útil y legible por humanos de una clase.Esto significa que la salida puede revelar información útil sobre su clase. Por ejemplo, si tuvieras una clase Person, podrías optar por tener como
ToString()
salida la identificación de la persona, su nombre, su apellido, etc. Esto es extremadamente útil al depurar o registrar.Con respecto a su ejemplo, es difícil saber si su anulación es útil sin saber qué es esta clase, pero la implementación en sí está bien.
fuente
Siempre es apropiado, pero considere cuidadosamente las intenciones detrás de lo que está mostrando.
Una mejor pregunta sería preguntar:
ToString () es la ventana al estado de un objeto. Énfasis en el estado como requisito. Los lenguajes fuertemente orientados a objetos como Java / C # abusan del modelo de programación orientada a objetos encapsulando todo en una clase. Imagina que estás codificando en un lenguaje que no sigue el modelo fuerte de OOP; considere si usaría una clase o una función. Si lo usa como una función (es decir, verbo, acción) y el estado interno solo se mantiene temporalmente entre la entrada / salida, ToString () no agregará valor.
Como otros han mencionado, es importante considerar lo que genera con ToString () porque podría ser utilizado por el depurador u otros sistemas.
Me gusta imaginar el método ToString como el parámetro --help de un objeto. Debe ser breve, legible, obvio y fácil de mostrar. Debe mostrar lo que el objeto no es lo que hace . Con todo eso en mente, consideremos ...
Caso de uso: análisis de un paquete TCP:
No es una captura de red solo a nivel de aplicación, sino algo con más carne como una captura pcap.
Desea sobrecargar ToString () solo para la capa TCP para poder imprimir datos en la consola. ¿Qué incluiría? Podría volverse loco y analizar todos los detalles de TCP (es decir, TCP es complejo) ...
Que incluye:
Pero, ¿le gustaría recibir toda esa basura si estuviera llamando a TCP.ToString () en 100 paquetes? Por supuesto que no, sería una sobrecarga de información. La elección fácil y obvia es también la más sensata ...
Exponga lo que la gente esperaría ver:
Prefiero una salida sensible que sea fácil de analizar para los humanos, pero YMMV .
Nada complejo, la salida no es para que las máquinas la analicen (es decir, a menos que las personas estén abusando de su código), el propósito previsto es la legibilidad humana.
Pero, ¿qué pasa con el resto de esa jugosa información de la que hablé antes? ¿No es eso útil también? Llegaré a eso, pero primero ...
ToString () uno de los métodos más valiosos y subutilizados de todos los tiempos
Por dos razones:
Razón 1: no abuse de la utilidad de ToString ():
Mucha gente usa ToString () para extraer una representación de cadena simple de un objeto. El manual de C # incluso dice:
Monitor, sin procesamiento adicional. Eso no significa que tome mi bonita representación de cadena del paquete TCP anterior y extraiga el puerto de origen usando una expresión regular :: cringe ::.
El derecho forma de hacer las cosas es llamar a ToString () directamente en la propiedad SourcePort (que por cierto es un ushort, por lo que ToString () ya debería estar disponible).
Si necesita algo más robusto para empaquetar el estado de un objeto complejo para el análisis automático, será mejor que utilice una estrategia de serialización estructurada.
Afortunadamente, estas estrategias son muy comunes:
Nota: A menos que esté usando PHP porque, herp-derp, hay una función para eso :: snicker ::
Razón 2: ToString () no es suficiente:
Todavía tengo que ver un lenguaje que implemente esto en el núcleo, pero he visto y usado variaciones de este enfoque en la naturaleza.
Algunos de los cuales incluyen:
Básicamente, ese desorden peludo del estado de un paquete TCP debería describirse para la legibilidad humana. Para evitar 'vencer a un caballo muerto' hablando de TCP, 'señalaré con el dedo' el caso # 1 donde creo que ToString () y ToVerboseString () están infrautilizados ...
Caso de uso: matrices:
Si usa principalmente un idioma, probablemente se sienta cómodo con el enfoque de ese idioma. Para personas como yo, que pasan de un idioma a otro, la variedad de enfoques puede resultar irritante.
Es decir, la cantidad de veces que esto me ha irritado es mayor que la suma de todos los dedos de cada dios hindú combinados.
Hay varios casos en los idiomas de uso común hacks y un pocos que consiguen que la derecha . Algunos requieren la reinvención de la rueda, algunos hacen un volcado poco profundo, otros hacen un volcado profundo, ninguno de ellos funciona como me gustaría ...
Lo que estoy pidiendo es un enfoque muy simple:
Donde x es el número de elementos en la primera dimensión e y es el número de elementos en la segunda dimensión o algún valor que indique que la segunda dimensión es irregular (¿rango mínimo / máximo tal vez?).
Y:
Con suerte, esto arroja algo de luz sobre un tema que me ha molestado durante mucho tiempo. Por lo menos, esparcí un pequeño cebo para que los PHPers votaran negativamente esta respuesta.
fuente
ToString()
está destinado a la depuración, ¿por qué es la única forma de extraer todo el texto de un StringBuilder, una función importante?Se trata tanto de buenas prácticas como de cualquier otra cosa, en realidad.
ToString()
se utiliza en muchos lugares para devolver una representación de cadena de un objeto, generalmente para el consumo de un ser humano. A menudo, esa misma cuerda se puede usar para rehidratar el objeto (piense enint
oDateTime
por ejemplo), pero eso no siempre es un hecho (un árbol, por ejemplo, puede tener una representación de cadena útil que simplemente muestra un recuento, pero claramente no puede usar eso para reconstruirlo).En particular, el depurador usará esto para mostrar la variable en las ventanas de observación, ventanas inmediatas, etc.
ToString
es realmente invaluable para la depuración.En general, también, este tipo a menudo tendrá un miembro explícito que también devuelve una cadena. Por ejemplo, un par Lat / Long podría tener
ToDecimalDegrees
que devuelve,"-10, 50"
por ejemplo, pero también podría tenerToDegreesMinutesSeconds
, ya que ese es otro formato para un par Lat / Long. Ese mismo tipo también podría anularseToString
con uno de esos para proporcionar un 'predeterminado' para cosas como depuración, o incluso potencialmente para cosas como renderizar páginas web (por ejemplo, la@
construcción en Razor escribe elToString()
resultado de una expresión que no es de cadena en el flujo de salida).fuente
object.ToString()
convierte un objeto en su representación de cadena. Si desea cambiar lo que se devuelve cuando un usuario llamaToString()
a una clase que ha creado, deberá anularToString()
esa clase.fuente
Si bien creo que ya se ha proporcionado la información más útil, agregaré mis dos centavos:
ToString()
está destinado a ser anulado. Su implementación predeterminada devuelve el nombre del tipo que, aunque puede ser útil a veces (especialmente cuando se trabaja con muchos objetos), no es suficiente en la gran mayoría de las veces.Recuerde que, a efectos de depuración, puede confiar en
DebuggerDisplayAttribute
. Puedes leer más sobre esto aquí .Como regla general, en las POCO siempre puede anular
ToString()
. Los POCO son una representación estructurada de datos, que generalmente pueden convertirse en una cadena.Diseñe ToString para que sea una representación textual de su objeto. Tal vez sus campos y datos principales, tal vez una descripción de cuántos elementos hay en la colección, etc.
Siempre trate de encajar esa cadena en una sola línea y tenga solo la información esencial. Si tiene una
Person
clase con propiedades de nombre, dirección, número, etc., devuelva solo los datos principales (nombre algún número de identificación).Tenga cuidado de no anular una buena implementación de
ToString()
. Algunas clases de framework ya se implementanToString()
. Anular esa implementación predeterminada es algo malo: la gente esperará un resultado determinadoToString()
y obtendrá otro.No tengas miedo de consumir
ToString()
. Lo único con lo que tendría cuidado es devolver información confidencial. Aparte de eso, el riesgo es mínimo. Claro, como algunos han señalado, otras clases usarán su ToString siempre que busquen información. Pero diablos, ¿ cuándo se considerará mejor devolver el nombre del tipo que obtener información real?fuente
Si no anula
ToString
, obtendrá la implementación de sus clases base, queObject
es solo el nombre de tipo corto de la clase.Si desea alguna otra implementación más significativa o útil de
ToString
, anótela.Esto puede resultar útil cuando se utiliza una lista de su tipo como fuente de datos para a,
ListBox
yaToString
que se mostrará automáticamente.Otra situación ocurre cuando desea pasar su tipo al
String.Format
que invocaToString
para obtener una representación de su tipo.fuente
Algo que nadie más ha mencionado todavía: al anular
ToString()
, también puede considerar implementarIFormattable
para poder hacer lo siguiente:Lo que puede resultar útil.
fuente
IFormattible
interfaz.System.Object
tendrá unToString()
método reemplazable , pero tiene razón en que el método del formateador no debería seroverride
y realmente debería hacer referencia a laIFormattible
interfaz para una conformidad completa.IFormattable
toma unIFormatProvider
parámetro. Gracias por editar tu publicación.Un beneficio de anular ToString () es el soporte de herramientas de Resharper: Alt + Ins -> "Formatear miembros" y escribe el ToString () por usted.
fuente
En algunos casos, facilita la lectura de valores de clases personalizadas en la ventana de observación del depurador. Si sé exactamente lo que quiero ver en la ventana de visualización, cuando anulo ToString con esa información, lo veo.
fuente
Al definir estructuras (de hecho, el usuario primitivas) Me parece que es una buena práctica tener a juego
ToString
, yParse
yTryParse
métodos, en particular para la serialización XML. En este caso, convertirá todo el estado en una cadena, de modo que pueda leerse más tarde.Sin embargo, las clases son estructuras más compuestas que normalmente serán demasiado complejas para usar
ToString
yParse
. SusToString
métodos, en lugar de guardar todo el estado, pueden ser una descripción simple que le ayude a identificar su estado, como un identificador único como un nombre o ID, o tal vez una cantidad para una lista.Además, como dijo Robbie, la anulación le
ToString
permite llamarToString
a una referencia tan básica como el tipoobject
.fuente
Puede usar eso cuando tenga un objeto con un significado no intuitivo de representación de cadena, como persona. Entonces, si necesita, por ejemplo, imprimir a esta persona, puede usar esta anulación para preparar su formato.
fuente
El
Object.ToString
método debe usarse solo con fines de depuración. La implementación predeterminada muestra el nombre del tipo de objeto que no es muy útil. Considere anular este método para proporcionar mejor información para el diagnóstico y la depuración. Tenga en cuenta que las infraestructuras de registro a menudo también utilizan el método ToString, por lo que encontrará estos fragmentos de texto en sus archivos de registro.No devuelva recursos de texto localizados dentro del
Object.ToString
método. La razón es que el método ToString siempre debe devolver algo que el desarrollador pueda entender. Es posible que el desarrollador no hable todos los idiomas que admite la aplicación.Implemente la
IFormattable
interfaz cuando desee devolver un texto localizado fácil de usar. Esta interfaz define una sobrecarga de ToString con los parámetrosformat
yformatProvider
. FormatProvider le ayuda a formatear el texto de una manera consciente de la cultura.Consulte también: Object.ToString e IFormattable
fuente
Más simple depende de cómo se vaya a utilizar su propiedad. Si solo necesita formatear la cadena una vez, no tiene mucho sentido anularla.
Sin embargo, parece que está anulando el método ToString para no devolver los datos de cadena normales para su propiedad, sino para realizar un patrón de formato estándar. Dado que está utilizando string.format con padding.
Debido a que dijo que está aprendiendo, el ejercicio también parece afectar los principios básicos de la programación orientada a objetos relacionados con la encapsulación y la reutilización del código.
El string.format que toma los argumentos que ha establecido para el relleno asegura que la propiedad se formateará de la misma manera cada vez para cualquier código que la llame. Además, en el futuro, solo tendrá que cambiarlo en un lugar en lugar de en muchos.
¡Gran pregunta y también grandes respuestas!
fuente
Encuentro útil anular el método ToString en las clases de entidad, ya que ayuda a identificar rápidamente los problemas en las pruebas, especialmente cuando una afirmación falla, la consola de prueba invocará el método ToString en el objeto.
Pero de acuerdo con lo que se ha dicho antes, se trata de dar una representación legible por humanos del objeto en cuestión.
fuente
Estoy satisfecho con las Directrices del marco mencionadas en otras respuestas. Sin embargo, me gustaría enfatizar los propósitos de visualización y depuración.
Tenga cuidado con cómo lo usa
ToString
en su código. Su código no debería depender de la representación de cadena de un objeto. Si es así, debe proporcionar losParse
métodos respectivos .Dado que
ToString
se puede usar en todas partes, puede ser un problema de mantenimiento si desea cambiar la representación de cadena de un objeto en un momento posterior. No puede simplemente examinar la jerarquía de llamadas en este caso para estudiar si algún código se romperá.fuente