2011-08-10 17 views
6

Acabo de encontrar un código que anula ToString() y devuelve información crítica (no solo información de depuración). Los usuarios de este tipo llamaron al ToString() y analizaron esos datos críticos.¿Se debe usar ToString para obtener información crítica?

mi opinión, de la lectura de diversas partes y piezas en los últimos años, es que tiene un ToString() más bien débil contract, es decir anularlo (si quieres) a pantalla algunas cosas con sentido.

Ver Dije pantalla allí? El código que encontré se basó en la representación textual de instancias de este tipo para ser muy específico; agregar cualquier cosa que no sea lo que se espera podría causar todo tipo de problemas.

Entonces, mi pregunta es, si la representación textual de un objeto es crítica, se debe usar ToString() o se debe usar un método/propiedad más explícito, p. AsText?

Respuesta

4

Personalmente comparto su preocupación. Microsoft's documentation afirma que el método ToString()

[...] convierte un objeto a su representación de cadena de modo que sea adecuada para su visualización.

Oracle's documentation para Object.toString() de Java es aún poco más fuerte:

El resultado debe ser una representación conciso pero informativo que es fácil para una persona a leer.

Veo esto como una fuerte indicación de que ToString() debe transmitir la información que es conveniente para los seres humanos. Un método que devuelve datos manipulados por otras partes de la aplicación debe tener un nombre más informativo. En mi opinión, incluso AsText() es demasiado genérico.

6

Esto parece un plan bastante malo. Si los usuarios del tipo necesitan datos, entonces ese tipo debería exponer los métodos para devolver esos datos. ¿Por qué las personas analizan la representación de cadena de un objeto cuando tienen acceso al objeto?

Existen, por supuesto, escenarios de serialización, pero están bien definidos y rara vez usan .ToString() para hacer su trabajo.

Si se requiere la representación textual de una cadena para fines no relacionados con la salida, entonces preferiría un método diferente (que pueda o no utilizar ToString() para hacer su trabajo). Esto ayuda tanto a los consumidores como a los implementadores; Sería realmente desafortunado que un nuevo codificador quisiera agregar información de dump dump en ToString() y quebrar a los consumidores de la clase.

ACTUALIZACIÓN: Como MattDavey señala, si se implementa IFormattable, entonces eso es una buena solución de compromiso: los consumidores llaman ToString(), pero con formatos específicos en mente, y el contrato fiable de lo que eso significa. Aún diferente de lo que están haciendo sus colegas, pero una opción que quizás sea más adecuada para ellos.

+1

Estoy completamente de acuerdo, pero argumentaría que el método ToString puede ser un buen candidato para generar datos de texto siempre que su objeto implemente IFormattable. Hay varios frameworks de enlace de datos que funcionarían mucho mejor con IFormattable.ToString que con MyCustomTextOutputMethod() ... pero eso no quiere decir que no puedas tener ambos :) – MattDavey

+0

@MattDavey Fair point, aunque eso es muy diferente a solo anulando el método estándar 'ToString()'. Voy a actualizar para abordar eso, sin embargo. – dlev

+0

Sí, es importante enfatizar la distinción entre los dos métodos. Lo que más me gusta de IFormattable es que en el patrón de implementación estándar, Object.ToString difiere a IFormattable.ToString ("G"), lo que le da una buena ruta de progresión :) – MattDavey

0

En mi opinión ToString() después de todo es un método que se puede utilizar en cualquier deseable manera, por ejemplo 5.ToString() convertir el int a string y devolverlo sin importar si era utilizar para la visualización o no, en el al contrario, en muchas situaciones estamos confiamos en esa información que se devuelve desde int.ToString() para realizar más operaciones.

1

No creo que haya una respuesta definitiva.

Yo argumentaría en el caso del uso de ToString(), porque cuando se crea una API en .NET se aprecia cuando se usan las convenciones de nomenclatura comunes en .NET, en lugar de utilizar nombres menos conocidos, como AsText(). Esta convención es seguida, por ejemplo, por la clase StringBuilder, ya que su ToString() devuelve información crítica.

+1

De acuerdo, el mismo escenario se aplica a System.IO.StringWriter. Parece que cuando el único propósito de los objetos es producir cadenas, usar el método ToString es una manera sensata de exponer el resultado final. – MattDavey

0

Sin lugar a dudas, no hay una respuesta definitiva a su pregunta. En mi opinión, los métodos como ToString o AsText solo deben usarse para proporcionar el estado interno de un objeto, p. para iniciar sesiónEn un lenguaje orientado a objetos, los aspectos funcionales deben derivarse utilizando una interfaz bien definida, p. GetOrderId, GetUserName.

0

No, yo no haría eso. Por ejemplo, si tuviera un objeto persona, ToString() podría devolver this.firstname + " " + this.lastname.. Lo usa para visualización automática, como agregar elementos a un cuadro de lista. Cuando se agrega el objeto, se muestra el nombre de la persona. No creo que pondría información crítica o sensata en la anulación.

+0

Una excepción a esta regla sería si el objeto implementado IFormattable, en cuyo caso el método ToString se vuelve mucho más flexible y poderoso para exponer datos como este ... – MattDavey

+0

@MattDavey - Agreeed –

1

Buena pregunta.

Para ser más explícito, crearía un método diferente para el formato diferente.

Ej: toJson() -> Representación JSON del objeto toXML() -> Representación XML del objeto. ... etc

Nota: probablemente hay una biblioteca que hace eso por ti .. en Java hay. no lo sé en C#

Como dices, analizar un toString() podría ocasionar problemas con el tiempo, ya que un desarrollador nuevo podría no saber que toString() tiene un formato específico.

Cuestiones relacionadas