2009-07-30 8 views
6

tengo el siguiente método:¿Cómo obtener el compilador de C# para inferir tipos genéricos?

public TResult Get<TGenericType, TResult>() 
          where TGenericType : SomeGenericType<TResult> 
          where TResult : IConvertible { 
    //...code that uses TGenericType... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

En este momento, un usuario de este método tiene que utilizar de esta manera:

//Notice the duplicate int type specification 
int number = Get<SomeGenericType<int>, int>(); 

¿Por qué tengo que especificar TResult en el Defintion método? El compilador ya conoce TResult desde que lo especifiqué en TGenericType. Lo ideal sería que (si el compilador de C# fue un poco más inteligente), mi método sería así:

public TResult Get<TGenericType>() 
          where TGenericType : SomeGenericType<TResult> 
          where TResult : IConvertible { 
    //...code that uses TGenericType... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

Así el usuario simplemente puede utilizar de esta manera:

//Much cleaner 
int number = Get<SomeGenericType<int>>(); 

¿Hay una manera de hacerlo ¿lo que quiero hacer?

+0

Creo que eliminar algunos calificadores como * estúpido * de la descripción de la pregunta ayudará. – EFraim

+0

Es el compilador que es estúpido, ¿verdad? ;) Eliminé el comentario extraño. Esta es en realidad una pregunta razonable sin eso. –

+0

Como le respondieron que no hay forma de usar solo algunos de los parámetros de tipo, quizás deba reformular su pregunta en términos de lo que le gustaría lograr. Tal como está, su pregunta es "¿cómo puedo hacer que el código de compilación del compilador C# viole la definición del lenguaje C#?" Como tal, debe ser cerrado como "no es una pregunta real". –

Respuesta

8

La especificación C# no permite inferir la mitad de los argumentos de tipo. Debe permitir que el compilador deduzca todos los argumentos de tipo (que no siempre son aplicables, como en su caso) o especifique todos manualmente.

ACTUALIZACIÓN (Responder al comentario): Aunque no estoy en el equipo de C# para dar una respuesta absoluta a su pregunta, mi especulación es que la complejidad de la resolución de sobrecarga (que ya está alucinante; sabes eso si lees esa sección de la especificación C#) aumentaría significativamente si quisieran permitir que la mitad de los tipos se infieran y la mitad no (especialmente considerando el hecho de que puedes sobrecargar los métodos únicamente por el número de argumentos genéricos).

+0

Pero, ¿por qué lo especificaron en la especificación C#? No es que haya algo inseguro al respecto. –

+0

Observe algunas de las reglas de C++, incluida la especialización parcial de las plantillas y cómo funcionan los especificadores de acceso. Por lo general, las cosas funcionan sin problemas, pero hay trampas acechando aquí y allá. Dado que una de las ideas detrás de Java y C# era evitar la complicación de C++, aceptando un pequeño inconveniente en su lugar, esto está en línea. –

1

Depende ...

Si sólo está utilizando SomeGenericType<TResult>, puede hacerlo:

public TResult Get<TResult>() where TResult : IConvertible { 
    SomeGenericType<TResult> myInstance = ... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

no hay necesariamente una manera de poner el primer tipo en ese país, en este caso . Como su ejemplo no está pasando en un SomeGenericType<TResult> explícitamente como un parámetro, sugiere que esto sea posible.

De lo contrario, debe especificar por completo todos sus argumentos genéricos. Desafortunadamente, así es como está en C#.

+0

Claro, pero necesito usar SomeGenericType en el método. Actualizaré mi código de muestra para dejarlo claro. –

+0

Sí, pero mira mi código: siempre que no se transmita como parámetro del método, puedes usar SomeGenericType en el método (es decir, si construyes uno en el método). Como conoces TResult, funciona bien. Como dije, puede funcionar en algunos casos ... –

+0

Lo siento, me refería a que necesito usar TGenericType (ver el código de muestra actualizado). –

Cuestiones relacionadas