2011-12-31 24 views
6

Tengo dos clases:Diseño modelo para permitir funciones para aceptar los tipos genéricos

public abstract class Uniform<T> 
public class UniformMatrix4 : Uniform<Matrix4> 

(hasta ahora .... habrá más que implementan tipos diferentes)

Y ahora digamos Quiero escribir una función que acepte cualquier objeto uniforme ... pero no puedo hacer eso porque no hay una clase llamada Uniform, solo el genérico Uniform<T>. Entonces, ¿cuál es el mejor enfoque para resolver este problema?

  1. Hacer Uniform<T> implemento IUniform
  2. Hacer Uniform<T> extienden Uniform
  3. Hacer todas mis funciones que aceptan un uniforme a ser genéricos demasiado para que puedan tomar una Uniform<T> directamente?
+0

¿Qué versión de C# se utiliza? ¿Has considerado el tipo dinámico? –

+0

Cuando no hay una clase llamada Uniforme, ¿cómo puede existir un objeto Uniforme? –

+0

Sin saber nada sobre el propósito de la clase, o sus firmas de métodos abstractos, es difícil dar una respuesta adecuada aquí. # 3 parece la respuesta obvia sin embargo. –

Respuesta

5

Haga que sus métodos sean genéricos también, y está bien.

Tenga en cuenta que usted siempre tiene la opción de utilizar todos los argumentos de tipo genérico en la función si es necesario, de esta manera:

public void MyMethod<TUniform, T>(TUniform uniform) where TUniform: Uniform<T> {...} 

El compilador suele inferir los argumentos de tipo por su cuenta cada vez que tenga un parámetro, por lo que la llamada, de hecho, se parece a una invocación de método normal en el código fuente de C#:

UniformMatrix4 uniform; 
MyMethod(uniform); // the types of the generic functions are inferred 
+0

Esto es lo que haría. En Mono bajo Ubuntu 11.10, no pude inferir tipos de argumentos bastante simples y terminé con una invocación fea: 'Ejecutar , String> (someClass);' –

+0

@JimSchubert, la inferencia de tipo solo funciona en argumentos, no en los tipos de devolución, ya que el tipo de devolución no es parte de la firma del método (que también es la razón por la que no puede haber sobrecargas que difieran solo en el tipo de devolución). En esos casos, debe especificar los tipos, pero hay una solución alternativa: convertir el resultado en un argumento 'out'. – Lucero

+1

Espera ... ¿por qué querrías declararlo así en lugar de lo que sugiere Domenic en su respuesta? Esto parece más detallado: ¿cuál es el beneficio? – mpen

3

cierto intimidar a publicar esta respuesta, pero creo que puede ser correcta:

public static Uniform<dynamic> MyMethod(dynamic myObject) { 
     //do stuff  
     return uniform; 
    } 

Aquí es un blog de Dino Esposito sobre el tema:

http://msdn.microsoft.com/en-us/magazine/ff796227.aspx

Cheers,

Matt

+0

Probablemente no lo entiendo, pero ¿cómo es esto relevante? Tal vez expandir en '// hacer las cosas' me ayudaría? –

+0

Oh, espera, si te refieres a los campos 'myObject' por tu nombre, los reconstruyes en un' Uniform '? Si ese es el caso (o no) quizás podrías expandir esta respuesta, ¿soy bastante curioso? –

+0

Bueno, de nuevo, un poco intimidado contribuyendo a una conversación con todos ustedes, gente de la reputación, pero lo que he estado haciendo es algo como esto: digamos que quiero usar un método genérico para construir un objeto de tipo desconocido en En tiempo de ejecución, crearía un nuevo ExpandoObject (myObject dinámico = new ExpandoObject();) y luego llenaría sus propiedades explícitamente (myObject.Name = "Matt";) o, en el caso de una consulta de Linq, instanciaría un IDictionary cuando recorriendo los datos devueltos (var item = myObject como IDictionary ; item [SomeKey] = SomeValue;). Gracias. –

2
public void MyMethod<T>(Uniform<T> uniform) { ... } 
+0

Sí ... esa es la opción n. ° 3. ¿Puedes explicar por qué es preferible? Lo que no me gusta de esto es que estás introduciendo 'T' que solo se usa una vez en la firma de la función y luego nunca más. No se usará para nada más – mpen

+2

@Mark, la variable de tipo 'T' aquí tiene el alcance del método, no de la clase. No duele en absoluto y normalmente no tiene costos de tiempo de ejecución adicionales asociados (suponiendo que 'T' siempre es un tipo de referencia). – Lucero

+0

Sé que tiene un alcance para el método ... solo digo. Aquí hay 3 opciones y estoy tratando de descubrir cuál es la mejor. – mpen

Cuestiones relacionadas