2011-07-08 25 views
14

Dadas las siguientes clases ...¿Por qué no se pueden inferir los tipos genéricos anidados?

public abstract class FooBase<TBar> where TBar : BarBase{} 
public abstract class BarBase{} 
public class Bar1 : BarBase{} 
public class Foo1 : FooBase<Bar1> {} 

... y el siguiente método ...

public TBar DoSomething<TFoo, TBar>(TFoo theFoo) 
    where TFoo : FooBase<TBar> 
    where TBar : BarBase 
{ 
    return default(TBar); 
} 

Por qué no puede la siguiente línea de código implica el tipo de retorno?

Bar1 myBar = DoSomething(new Foo1()); 

En lugar de eso tienen que especificar los tipos genéricos como esto ...

Bar1 myBar = DoSomething<Foo1, Bar1>(new Foo1()); 

Respuesta

21

tipo de método de inferencia hace caso omiso de las limitaciones genéricas sobre los parámetros de tipo de método (*). Método tipo razones de inferencia solo acerca de las deducciones que se pueden hacer comparando argumentos a tipos de parámetros formales. Como el único parámetro de tipo genérico que aparece en sus tipos de parámetros formales es TFoo, no hay forma de deducir TBar.

Muchas personas creen que esta decisión de diseño es incorrecta, incorrecta o incorrecta. Aunque tomo su punto, esta decisión conduce a lo que, en mi opinión, son algunas buenas propiedades. Para un extenso debate sobre este tema, ver el bazillion o más comentarios en este artículo de blog que me dicen que estoy mal, mal, mal:

http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx


(*) Nótese que he dicho limitaciones en Los parámetros del tipo de método se ignoran, no son restricciones en general. Si los tipos de parámetros formales deducidos son tipos genéricos construidos de forma tal que la construcción infringe sus restricciones de parámetro de tipo, este hecho hace que la inferencia de tipo falle y el método no es candidato para la resolución de sobrecarga. Pero bajo ninguna circunstancia hacemos hacer una deducción de una restricción que no sea "Hmm, claramente esto no va a funcionar".

+0

Creo que algunas personas se preguntarán por qué no ** probaremos ** usar la restricción para inferir el tipo. Otra forma de pensar sobre esto, es que si considera primero debemos determinar qué tipos concretos se están utilizando para TFoo y TBar, entonces cualquier código que haga referencia a esos tipos ahora usa el tipo concreto. En el caso de 'FooBase ', aquí estamos diciendo ** después ** sabes qué tipo 'TBar' es, entonces' FooBase 'se convertirá en 'FeeBase '. Esta restricción no se puede usar como parte de la inferencia de tipo, porque no conocemos el tipo hasta que se complete la inferencia. Sería lógica circular. – AaronLS

Cuestiones relacionadas