Esperaba hacer algo como esto, pero parece ser ilegal en C #:
public Collection MethodThatFetchesSomething<T>()
where T : SomeBaseClass
{
return T.StaticMethodOnSomeBaseClassThatReturnsCollection();
}
Recibo un error en tiempo de compilación: "'T' es un 'parámetro de tipo', que no es válido en el contexto dado".
Dado un parámetro de tipo genérico, ¿cómo puedo llamar a un método estático en la clase genérica? El método estático debe estar disponible, dada la restricción.
Respuestas:
En este caso, debe llamar directamente al método estático en el tipo restringido. C # (y CLR) no admiten métodos estáticos virtuales. Entonces:
... no puede ser diferente a:
Pasar por el parámetro de tipo genérico es una indirección innecesaria y, por lo tanto, no es compatible.
fuente
return SomeBaseClass.StaticMethodOnSomeBaseClassThatReturnsCollection();
Funcionaría? Si es así, es posible que desee agregar eso a su respuesta. Gracias. Funcionó para mí. En mi caso, mi clase tenía un parámetro de tipo, así que lo hicereturn SomeBaseClass<T>.StaticMethodOnSomeBaseClassThatReturnsCollection();
y funcionó.Para desarrollar una respuesta anterior, creo que la reflexión está más cerca de lo que quieres aquí. Podría dar 1001 razones por las que debería o no debería hacer algo, solo responderé a su pregunta tal como se me pide. Creo que deberías llamar al método GetMethod en el tipo de parámetro genérico e ir desde allí. Por ejemplo, para una función:
Donde T es cualquier clase que tenga el método estático fetchAll ().
Sí, soy consciente de que esto es terriblemente lento y puede fallar si someParent no fuerza a todas sus clases secundarias a implementar fetchAll pero responde la pregunta tal como se le preguntó.
fuente
La única forma de llamar a dicho método sería a través de la reflexión. Sin embargo, parece que podría ser posible envolver esa funcionalidad en una interfaz y usar un patrón IoC / factory / etc. basado en instancias.
fuente
Parece que está intentando utilizar genéricos para evitar el hecho de que no existen "métodos estáticos virtuales" en C #.
Desafortunadamente, eso no va a funcionar.
fuente
A partir de ahora, no puedes. Necesita una forma de decirle al compilador que T tiene ese método y, actualmente, no hay forma de hacerlo. (Muchos están presionando a Microsoft para que expanda lo que se puede especificar en una restricción genérica, por lo que tal vez esto sea posible en el futuro).
fuente
Aquí, publico un ejemplo que funciona, es una solución
fuente
public T : SomeBaseClass
significa?Solo quería decir que a veces los delegados resuelven estos problemas, según el contexto.
Si necesita llamar al método estático como una especie de fábrica o método de inicialización, entonces puede declarar un delegado y pasar el método estático a la fábrica genérica relevante o lo que sea que necesite esta "clase genérica con este método estático".
Por ejemplo:
Desafortunadamente, no puede hacer cumplir que la clase tenga el método correcto, pero al menos puede hacer cumplir en tiempo de compilación que el método de fábrica resultante tenga todo lo que espera (es decir, un método de inicialización con exactamente la firma correcta). Esto es mejor que una excepción de reflexión en tiempo de ejecución.
Este enfoque también tiene algunos beneficios, es decir, puede reutilizar métodos init, hacer que sean métodos de instancia, etc.
fuente
Debería poder hacer esto usando la reflexión, como se describe aquíDebido a que el enlace está muerto, encontré los detalles relevantes en la máquina de retorno:
fuente