Uso del tipo de objeto como parámetro

Me he estado preguntando acerca de esto: ¿apoyaría usar simplemente un objeto como un parámetro en su método? Mi razón detrás de hacer esto sería sobrecargar. Actualmente, estoy tratando de crear un método que se adapte a muchos tipos de datos diferentes: string, decimal, DateTime... la lista continua.

Sin embargo, se está poniendo un poco complicado, así que estaba pensando en hacer lo siguiente

public void GenericMethod(object val)
{
    if (val is string)
        // process as string
    else if (val is decimal)
        // process as decimal
    else if (val is DateTime)
        // do something for dt
    else
        // ...
}

¿Qué opinas de un método así? ¿Incurriría en gastos generales innecesarios? (durante la comprobación de tipo) ¿Lo has implementado? Dígame...

EDIT: Sí, y solo una nota al margen, estoy un poco familiarizado con la sobrecarga. Pero se vuelve un poco molesto cuando hay como más de 10 sobrecargas...

preguntado el 22 de mayo de 12 a las 17:05

Si bien eso técnicamente funciona, ciertamente no es una buena idea a menos que tenga un razón de peso para hacerlo. -

En última instancia, depende de lo que esté haciendo en su método y de cuán diferente sea su método para cada tipo. Idealmente, usaría genéricos y haría que el parámetro fuera genérico si todos son similares. Si son radicalmente diferentes, definitivamente no es una buena idea. Es imposible decir lo que sería apropiado en su caso. -

6 Respuestas

Sí, eso funcionaría. Sin embargo, hay mejores maneras de hacer esto.

Su mejor apuesta es usar sobrecargas:

public void GenericMethod(string val)
{
        // process as string
}
public void GenericMethod(decimal val)
{
    // process as decimal
}

etc.

Siempre que use un is palabra clave en su código que es una gran pista de que probablemente se está olvidando de usar algunos principios importantes de OO: sobrecargas, subclases o similares.

Las sobrecargas no son realmente tan molestas para trabajar, solo para escribir. Recuerda, no estás codificando esto para ti hoy, lo estás codificando para ti dentro de tres meses. cuando tienes que leer el código y descubrir por qué diablos lo hiciste de esa manera, o de dónde en el mundo proviene ese error.

Otra razón más para evitar la técnica de "encender el tipo" es la coherencia con el marco .NET (y, por lo tanto, con las expectativas de las personas). Seguir Console.Write y la otra amplia variedad de métodos que se anulan dentro y bajo una clase determinada.

contestado el 22 de mayo de 12 a las 18:05

Sí, todos hemos pasado por las situaciones de "por qué diablos lo hiciste de esa manera" y "de dónde en el mundo viene ese error". Estaba pensando que a otras personas les podría resultar más efectivo tener simplemente un método con el que trabajar, en lugar de tener que abrirse camino a través de muchas sobrecargas. - mate

@matt... aunque no realmente. Estoy acostumbrado a cómo .NET hace las cosas: una sobrecarga por tipo, y si intentara cambiarlo, me confundiría bastante. - chris pfohl

Me he estado preguntando acerca de esto: ¿apoyaría usar simplemente un objeto como parámetro en su método?

Muy raramente Si hay un conjunto fijo de tipos que son compatibles correctamente, y de lo contrario arrojará una excepción, entonces usaría sobrecargas.

Si realmente puedes aceptar cualquier y manejará un tipo no especialmente compatible de alguna manera bien conocida, entonces está bien aceptar object. Eso es lo que hace LINQ to XML en todas partes, y el resultado es una API muy limpia. Sin embargo, lo haría con mucho cuidado, es raramente una buena idea.

Y sí, habría una sobrecarga. Sin embargo, normalmente no tomaría eso como la base de la decisión: los gastos generales serán lo suficientemente pequeños como para ser insignificantes en la mayoría de los casos. Diseñe su API de la forma más limpia posible y luego averigüe si va a causar un cuello de botella.

contestado el 22 de mayo de 12 a las 17:05

Sí, incurriría en gastos generales tanto para la verificación de tipo como para el encajonado/desencajonado del tipo de valor. Recomendaría las sobrecargas.

Otra posibilidad, siempre y cuando no hagas muchas operaciones matemáticas con el número, sería convertirlo en un método genérico. Sin embargo, la aritmética es bastante difícil con los genéricos, ya que no hay restricciones para los tipos de valor que permiten el uso de operadores.

contestado el 22 de mayo de 12 a las 17:05

No hay necesidad de esos!

Simplemente declare tantos métodos con el mismo nombre como desee y tome cada tipo como argumento en cada método. [Esto se llama sobrecarga. por ejemplo, puede que hayas visto eso +1 Overloads al lado de Métodos, lo que implica que hay 1 Método más con el mismo nombre pero con diferentes tipos de argumentos]

Di así:

void Method(decimal d)
{
    //Process Decimal
}
void Method(string s)
{
    //Process String
}

Por defecto, encontrará su propio método según el Tipo.

contestado el 22 de mayo de 12 a las 17:05

Hay casos en los que su enfoque tiene sentido. Lo he usado antes, principalmente cuando tengo un montón de procesamiento que es el mismo para diferentes tipos de datos.

Pero esto no es sobrecargar. La sobrecarga sería definir diferentes firmas para el mismo nombre de método como este:

public void GenericMethod(string val)
{
    // process as string
}

public void GenericMethod(decimal val)
{
    // process as decimal
}

public void GenericMethod(DateTime val)
{
    // do something for dt
}

// Etc.

Y para algunos casos, este enfoque tiene más sentido.

contestado el 22 de mayo de 12 a las 17:05

Parece que los débiles de mente están fuera, rechazando las respuestas sin las uvas para explicar por qué. - jonathan madera

Implementando muchas sobrecargas una de ellas toma object no es problema. Echa un vistazo a Console.WriteLine sobrecargas por ejemplo. http://msdn.microsoft.com/en-us/library/system.console.writeline.aspx Sin embargo, tenga cuidado de que int, por ejemplo, pueda entrar en conflicto con double:

int sum(int i, int j)
{
 return i + j;
}

double sum(double i, double j)
{
 return i + j;
}

object sum(object i, object j)
{
  return i.ToString() + j.ToString();
}

==============================

static void Main()
{
   sum(1, 2); // Error: ambigous call between `int` and `double` versions
   sum(1.0, 2.0); // calls double version, although 1.0 and 2.0 are objects too
   sum("Hello", "World"); // object
}

contestado el 22 de mayo de 12 a las 17:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.