2010-12-18 11 views
10

¿Por qué debo proporcionar tipos de parámetros explícitamente genéricos mientras que el compilador debe inferir el tipo? Uso¿Por qué debo proporcionar tipos de parámetros explícitamente genéricos mientras que el compilador debe inferir el tipo?

public static T2 Cast<T1,T2>(this T1 arg) where T2 : class where T1 : class 
{ 
    return arg as T2; 
} 

muestra:

objOfTypeT2 = objOfTypeT1.Cast<TypeT1,TypeT2>(); 


En comparación con mi uso deseado con un compilador más inteligente:

objOfTypeT2 = objOfTypeT1.Cast<TypeT2>(); 

o tal vez debería ser más inteligente :-)

Ten en cuenta que I prov ide el tipo de devolución. No deseo proporcionar el objeto al que he llamado la función, el método es Método de extensión.

+0

¿Qué hay de malo en la forma en la fundición (s) normal? –

+1

¿Por qué no simplemente hacer un T T estático público (este valor de objeto) {valor de retorno como T;}? – Rauhotz

+0

@Rauhotz Tuve lo que mencionaste, solo curiosidad y buscando otra sobrecarga, permíteme usarla con tipos de valores, porque no puedo sobrecargar con restricciones genéricas. –

Respuesta

11

La especificación limita la inferencia del parámetro de tipo para métodos genéricos a todo o nada. No puedes tener una inferencia parcial.

La razón de ser es, probablemente, simplificar las reglas de inferencia de tipo (que ya son bastante complejas, ya que también deben tener en cuenta las reglas de sobrecarga).

+0

Lo adiviné, así que reordeno los parámetros para que el tipo inferido sea el último parámetro pero no haya posibilidad. –

+0

@Jani: El orden realmente no importa aquí. O bien el compilador puede deducir todos los argumentos de tipo para usted, en cuyo caso puede omitirlos todos, o no puede inferir al menos uno. En este último caso, siempre tendrá que especificar * todos * explícitamente. –

15

La inferencia no tiene en cuenta el tipo de devolución; sin embargo, puedes intentar dividir los genéricos; por ejemplo, podría escribir código para permitir:

.Cast().To<Type2>() 

por tener (no probado; sólo indicativas)

public static CastHelper<T> Cast<T>(this T obj) { 
    return new CastHelper<T>(obj); 
} 
public struct CastHelper<TFrom> { 
    private readonly TFrom obj; 
    public CastHelper(TFrom obj) { this.obj = obj;} 
    public TTo To<TTo>() { 
     // your code here 
    } 
} 
+0

Tenga en cuenta que proporciono el tipo de devolución. No deseo proporcionar el objeto al que llamé la función, el método es un Método de extensión. –

+0

@ Jani y mira el ejemplo - No incluyo el tipo de; solo el tipo de destino. –

+0

Sí, diría que es la única solución en este momento. –

Cuestiones relacionadas