2009-03-14 12 views
17

La manera más fácil de explicar lo que quiero decir es con una muestra de código. Esto no compila, pero ¿hay alguna manera de conseguir este efecto:¿Se pueden usar métodos genéricos en C# si el tipo es desconocido hasta el tiempo de ejecución?

foreach(Type someType in listOfTypes) 
{ 
    SomeMethod<someType>(); 
} 

sería muy conveniente si eso funcionaría, pero no es así. ¿Hay alguna otra forma de lograr lo mismo que arriba, y por qué C# no permite que sea una declaración legal?

Editar: Parece que la única manera de hacerlo es a través de la reflexión, que puede ser demasiado lenta para nuestras necesidades. ¿Alguna idea de por qué no hay una manera eficiente integrada y si algo así está en proceso para C# 4.0?

+0

No estoy seguro de lo que estás tratando de lograr aquí. ¿Podría proporcionar más contexto y/o una explicación de lo que SomeMethod necesita hacer (y por qué necesita hacerlo para una lista de tipos), por favor? – Noldorin

+0

Sí, puedes hacer eso con la reflexión como otros lo han mencionado, pero ten en cuenta que la reflexión es sangrientamente lenta. Si el rendimiento es importante en su caso, considere algún otro enfoque. –

+0

Necesito indizar todos los tipos en nuestra base de datos de objetos sin preocuparme cuando se agregan o eliminan nuevos tipos, etc. – Davy8

Respuesta

22

Puede usar el reflejo. Suponiendo que el objeto actual contiene el método SomeMethod(), el código para hacerlo sería el siguiente:

GetType().GetMethod("SomeMethod"). 
    MakeGenericMethod(new Type[] { someType }).Invoke(this, null); 

Tenga en cuenta que si es SomeMethod() no pública, su código no puede ejecutar en entornos de menor confianza.

23

¿Por qué C no permite que esto sea una declaración legal?

Como han señalado otros, no puede hacer esto. Por qué no? Bueno, considere su ejemplo:

foreach(Type someType in listOfTypes) 
{ 
    SomeMethod<someType>(); 
} 

en cuenta que cada tipo en la lista de tipos no puede conocerse hasta tiempo de ejecución, mientras que el parámetro de tipo de SomeMethod debe ser conocido en tiempo de compilación . Es imposible para el compilador decir queSomeMethod<T> para resolver su invocación, por lo que esto es ilegal.

En C# 4, esto y muchas otras cosas similares serán posibles con la inclusión del DLR en el CLR. En particular, la invocación de método dinámico le permitirá invocar métodos que pueden no conocerse en tiempo de compilación.

+0

Ojalá pudiera marcar 2 respuestas aceptadas ya que supongo que hice 2 preguntas. – Davy8

+3

¡No se preocupe, no hay resentimientos! StackOverflow está repleto de buenas respuestas que no son aceptadas. Escogiste la que captaba lo que más querías decir: solo estoy agregando un poco de información extra para los curiosos.;) –

+0

Ahora que C# 4 ha sido liberado, puede actualizar su respuesta con un ejemplo usando 'dynamic' –

Cuestiones relacionadas