2009-07-23 8 views
64

Esto no es realmente un problema, sin embargo, tengo curiosidad. Cuando guardo una cadena en permite decir una DataRow, se convierte en Object. Cuando quiero usarlo, tengo que convertirlo en ToString. Por lo que yo sé que hay varias maneras de hacer esto, primero esCasting vs Convertir un objeto a String, cuando objeto realmente es una cadena

string name = (string)DataRowObject["name"]; //valid since I know it's a string 

y otra es:

string name = DataRowObject["name"].ToString(); 

Estoy interesado en lo que es la diferencia entre ambos? ¿El primero es más eficiente? (Esto es solo una especulación, en mi cabeza el método ToString() es implementado por algún mecanismo de bucle donde simplemente lanzarlo "podría" ser más rápido, sin embargo, esto es solo un "presentimiento" que tengo).

¿Hay alguna manera más rápida/más elegante de hacer esto?

¿Alguien puede aclarar esto por mí?

+3

Sé que mencionó que el objeto es una cadena, pero en caso de que no esté seguro de que el objeto devuelto sea nulo, también puede usar "Convert.ToString (DataRowObject [" name "]);" Esto tiene el beneficio adicional de devolver una cadena vacía (string.empty) si el objeto es nulo, para evitar excepciones de referencia nula. – n00b

Respuesta

47

Los dos están diseñados para diferentes propósitos de . Se supone que el método ToString de cualquier objeto devuelve una cadena representación de ese objeto. Casting es bastante diferente, y la palabra 'as' realiza una conversión condicional, como se ha dicho . La palabra clave 'as' básicamente dice "consígame una referencia de este tipo a ese objeto si ese objeto es de este tipo", mientras que ToString dice "consígame una representación de cadena de ese objeto".El resultado puede ser el mismo en algunos casos, pero los dos deben nunca se consideran intercambiables porque, como ya he dicho, existen para diferentes propósitos . Si su intención es lanzar, siempre debe usar un yeso, NO ToString.

de http://www.codeguru.com/forum/showthread.php?t=443873

ver también http://bytes.com/groups/net-c/225365-tostring-string-cast

+0

Entonces, si entiendo esto correctamente. .ToString siempre devolverá una cadena del objeto. Mientras que el lanzamiento fallará si no se puede devolver como una cadena? – DaImTo

+1

@DaImTo: Cuando lanza un objeto del tipo A al tipo B (si el lanzamiento) es exitoso, tendrá un nuevo objeto, que puede volver a lanzar al tipo A nuevamente. Casting no cambia quiénes son (el núcleo), sino que cambia cómo se verán. La conversión, en casos comunes, es un boleto de ida. Hace que un nuevo objeto (solo) represente para el objeto viejo. Ej: un objeto de estudiante st cuando convert toString() será una cadena con aspecto de estudiante: @ 1343; 43234. ¿Crees que puedes volver a convertirlo en un estudiante con valor de campo? – Andiana

+0

@Andiana In Ref Exam libro para C# dice "Al crear sus propios tipos, puede anular ToString para devolver una representación de cadena de su objeto. Si es necesario, puede crear un método Parse and TryParse que convierte la cadena de nuevo al objeto original. La implementación de la interfaz IFormattable es necesaria para que su objeto pueda ser utilizado por la clase Convert ". ¿Podría explicarlo a la luz de lo que dijo anteriormente? Gracias –

27

Si sabes que es String entonces, por supuesto, empújala a String. Lanzar tu objeto va a ser más rápido que llamar a un método virtual.

Editar: Éstos son los resultados de algunas de evaluación comparativa:

============ Casting vs. virtual method ============ 
cast 29.884 1.00 
tos 33.734 1.13 

he usado de Jon Skeet BenchmarkHelper así:

using System; 
using BenchmarkHelper; 

class Program 
{ 
    static void Main() 
    { 
     Object input = "Foo"; 
     String output = "Foo"; 

     var results 
      = TestSuite.Create("Casting vs. virtual method", input, output) 
      .Add(cast) 
      .Add(tos) 
      .RunTests() 
      .ScaleByBest(ScalingMode.VaryDuration); 

     results.Display(ResultColumns.NameAndDuration | ResultColumns.Score, 
       results.FindBest()); 
    } 

    static String cast(Object o) 
    { 
     return (String)o; 
    } 

    static String tos(Object o) 
    { 
     return o.ToString(); 
    } 
} 

lo que parece que la fundición es de hecho ligeramente más rápido que llamando al ToString().

+1

@Andrew: ¿Has comparado eso? Puede haber cambiado, pero la última vez que lo comparaté descubrí que el método virtual era realmente más rápido. No esperaba que lo fuera, pero lo fue. –

+0

@Jon - ¡No, no lo hice!Tendré que verificarlo para estar seguro. –

+1

@ AndrewHare- El enlace de Jon lleva a 505 – TheGeekZn

16

Básicamente en su caso, es mejor dejar el tipo de conversión porque .ToString() puede ocultar errores. Por ejemplo, su esquema de base de datos cambió y el nombre ya no es de tipo cadena, pero con .ToString() su código aún funciona. Entonces, en este caso, es mejor usar el tipo de conversión.

Aquí consiste en la realización de String.ToString() - nada especial =)

public override string ToString() 
{ 
    return this; 
} 
+5

+1 para descompilar String.ToString() –

5

downcasting es una operación relativamente lenta desde CLR tiene que realizar varias comprobaciones de tipo en tiempo de ejecución. Sin embargo, en este escenario particular, la conversión a string es más apropiada que llamar al ToString() por razones de coherencia (no puede llamar al ToInt32 en object, sino que puede convertirlo al int) y mantenerlo.

+0

Puede que no sea tan lento como crees, consulta mi respuesta. –

2

En este caso:

string name = DataRowObject["name"].ToString(); 

ya que es un string, creo que el método de un objeto de cadena ToString() es simple como:

return this; 

así que en mi humilde opinión no hay ninguna penalización de rendimiento.

PS Soy programador de Java, por lo que este guion es solo una suposición.

+0

Creo que DataRowObject no tiene conocimiento de los tipos y almacena todo como Objetos, por lo que definitivamente no es tan simple como devolver esto. –

+3

@martjin_himself Bienvenido al mundo de la orientación a objetos, déjame presentarte un nuevo amigo: Polimorfismo. – fortran

+0

@fortran ¿te importaría elaborar? Soy consciente de que todo es un Objeto y el polimorfismo te permite tratar una cuerda como si fuera un Objeto, sin embargo, eso es irrelevante aquí, a menos que me falta algo. aplausos –

1

ToString() no realiza una conversión de forma predeterminada. Su objetivo es devolver una cadena que represente el tipo (por ejemplo, "System.Object").

Si desea evitar la conversión, podría intentar pensar en una implementación fuertemente tipada (utilizando genéricos, por ejemplo) y evitar DataRowObject por completo.

2

Para objeto de datos, le sugiero que utilice la palabra clave "como", como el siguiente código.

string name = DataRowObject["name"] as string; 

Por favor, compruebe antes de usar valor.

if(name != null) 
{ 
    // statement for empty string or it has value 
} 
else 
{ 
    // statement for no data in this object.  
} 
+0

sería una versión más concisa de la misma: 'string name = (fila ["nombre"] como cadena) ?? "predeterminado"; ' –

4

Quiero hacer un comentario más

Si se va a utilizar de calidad: string name = (cadena) DataRowObject [ "nombre"] obtendrá una excepción: No se puede convertir objeto de escriba 'System.DBNull' para escribir'System.String 'en caso de que el registro en la tabla de la base de datos tenga un valor nulo.

En este escenario hay que utilizar:. String name = DataRowObject [ "nombre"] ToString() o

Hay que comprobar si hay valor nulo como

if(!string.IsNullOrEmpty(DataRowObject["name"].ToString())) 
{ 
string name = (string)DataRowObject["name"]; 
} 
else 
{ 
//i.e Write error to the log file 
string error = "The database table has a null value"; 

} 
0

sé que usted ha mencionado que el objeto es una cadena, pero en caso de que tengas miedo de que el objeto devuelto sea nulo, también puedes usar "Convert.ToString (DataRowObject [" name "]);" Esto tiene el beneficio adicional de devolver una cadena vacía (string.empty) si el objeto es nulo, para evitar excepciones de referencia nula (a menos, por supuesto, que desee una excepción en tales casos).

+0

Hay un beneficio adicional al usar" Convert.ToString "y es que puede pasar un valor nulo sin tener que lanzar una excepción. [enlace] (http://msdn.microsoft.com/en-us/library/astxcyeh.aspx) – Remy

Cuestiones relacionadas