2010-02-16 13 views
5

Lo que estoy haciendo es buscar un valor para un campo en particular en la tabla hash. El objeto puede ser un puñado de tipos primitivos cuyo valor está destinado a colocarse dentro de XML, pero sale de la tabla hash como un objeto. Así que tengo el problema de necesitar decidir qué tipo es, lanzarlo y luego usar ese tipo ToString. Sería bueno si no necesitara lanzarlo, pero luego llamará a ToString en el tipo de objeto y no al método de contraparte en el tipo real.Una forma limpia de convertir objetos a un tipo real

El siguiente código es funcionalmente correcto, pero no me siento cómodo con él. Tal vez seguir este camino de la comodidad me lleve a ser un purista. De cualquier manera, apreciaría mucho una mejor manera de escribir esto, si eso existe.

public string GetColumnValue(string columnName) 
     { 
      object value = item[columnName]; 

      if (value == null) 
       return string.Empty; 

      if (value.GetType() == typeof(string)) 
      { 
       return (string)value; 
      } 
      else if (value.GetType() == typeof(double)) 
      { 
       return ((double)value).ToString(); 
      } 
      ... 
     } 

Respuesta

8

Si todo lo que está haciendo es llamar ToString, debido a la naturaleza polimórfica de C#, el ToString llamará a la aplicación correcta, incluso si todo lo que tiene es una referencia al objeto.

ej .:

var d=DateTime.Now; 
object od=d; 
Console.WriteLine(od.ToString()); 
Console.WriteLine(d.ToString()); //same as previous line 
+1

Esto funciona para los tipos básicos, pero puede no funcionar bien para tipos personalizados; depende de lo que se puede devolver en el elemento [columnName] ... –

+0

Reed, ¿puede dar un ejemplo? – spender

+0

Honestamente, no pensé que esto funcionaría. Entonces, para los argumentos, ¿cómo se puede llamar explícitamente a una implementación de ToString en un tipo particular de árbol de herencia? –

1

Dependiendo de su lista de tipos aceptables, es posible que desee considerar el uso de Convert.ToString y/o la IConvertable interface.

Esto le permitirá manejar la mayoría de los tipos primitivos en una sola toma.

Sin embargo, aún necesitará controlar su comprobación nula.

0

¿Por qué no puede simplemente usar .ToString() en value ya que .ToString() se hereda del objeto? Se llamará a .ToString() para el tipo apropiado más arriba en la cadena de herencia.

+0

Aún necesita el cheque nulo, sin embargo. –

1

edición

códigos de los exámenes aquí si alguien está interesado: http://gist.github.com/raw/305787/dc5349d9f6fa37ee5d621b43ec92dade60fe1c8d/ToStringTests.cs

A continuación encontrará mi respuesta original. Alguien señaló que podría tener un tipo que no tiene un ToString() que le guste (porque usa Object o algo más arriba en la cadena). La mejor manera de manejar esto es de 3.0 + con un método de extensión de esta manera:

public static class ToStringExpander 
    { 
     public static string MyToString (this Object x) 
     { 
      return x.ToString(); 
     } 

     public static string MyToString (this mytype x) 
     { 
      return "This is the to string of mytype!"; 
     } 
    } 

Ahora mytype trabajará con el GetColumnValue a continuación si cambia ToString() para MyToString()

post original

Esto hará lo que quiera.

public string GetColumnValue(string columnName) 
    { 
     object value = item[columnName]; 

     if (value == null) 
      return string.Empty; 

     return object.ToString(); 
    } 

o si desea buscar la vieja escuela:

public string GetColumnValue(string columnName) 
    { 
     return (item[columnName] == null ? string.Empty : item[columnName].ToString()); 
    } 

por supuesto verdadera vieja escuela sería hacer una macro #define ...

+1

Las reglas de resolución de nombre de método requieren que los métodos de miembro de un objeto se seleccionen con preferencia a cualquier método de extensión que pueda estar dentro del alcance. Así que estoy bastante seguro de que lo que estás sugiriendo aquí no funcionará. –

+0

Sí, acabo de probarlo, el libro que estaba leyendo implicaba que actuaría como lo describí, cambié la respuesta a una nueva solución. – Hogan

0

ToString() es un método virtual. Esto significa que cualquier llamada a ese método, en tiempo de ejecución, seleccionará la implementación correcta (el "tipo más derivado"). Dado que todos los tipos primativos anulan ToString() para hacer lo correcto, no hay motivo para realizar ningún tipo de conversión a ningún tipo de variable.

Para un método virtual, el tipo de variable no importa al seleccionar la implementación correcta. Lo único que importa es el tipo de tiempo de ejecución del objeto al que se hace referencia.

int x = 10; 
object o = x; 
x.ToString(); 
o.ToString(); 

Ambas llamadas a ToString() ejecutará el mismo código (menos el unboxing que se produce en la versión object, ya int es un tipo de valor).

Cuestiones relacionadas