2010-11-15 11 views
11

¿Por qué el compilador de C# no infiere el hecho de que FooExt.Multiply() satisface la firma de Functions.Apply()? Debo especificar una variable de delegado independiente de tipo Func<Foo,int,int> para que el código funcione ... pero parece que la inferencia de tipos debería manejarlo. ¿Me equivoco? Y, si es así, ¿por qué?¿Por qué el compilador de C# no deduce automáticamente los tipos en este código?

EDIT: El error de compilación recibida es:

Los argumentos de tipo para el método FirstClassFunctions.Functions.Apply<T1,T2,TR>(T1, System.Func<T1,T2,TR>, T2)' no pueden inferirse a partir del uso. Intente especificar los argumentos de tipo explícitamente

namespace FirstClassFunctions { 
    public class Foo { 
     public int Value { get; set; } 

     public int Multiply(int j) { 
      return Value*j; 
     } 
    } 

    public static class FooExt { 
     public static int Multiply(Foo foo, int j) { 
      return foo.Multiply(j); 
     } 
    } 

    public static class Functions { 
     public static Func<TR> Apply<T1,T2,TR>(this T1 obj, 
               Func<T1,T2,TR> f, T2 val) { 
      return() => f(obj, val); 
     } 
    } 


    public class Main { 
     public static void Run() { 
      var x = new Foo {Value = 10}; 
      // the line below won't compile ... 
      var result = x.Apply(FooExt.Multiply, 5); 
      // but this will: 
      Func<Foo, int, int> f = FooExt.Multiply; 
      var result = x.Apply(f, 5); 
     } 
    } 
+0

Lo siguiente debería funcionar también: 'x.Apply (nuevo Func (FooExt.Multiply), 5)'. ¿Cuál es el error de compilación? – thecoop

+1

Parece compilar bien para mí, en .NET 4.0. –

+0

posible duplicado de [C# 3.0 tipo genérico de inferencia - pasando un delegado como un parámetro de función] (http://stackoverflow.com/questions/407983/c-3-0-generic-type-inference-passing-a-delegate- as-a-function-parameter) – thecoop

Respuesta

5

creo que esto es el resultado de la incapacidad del VS2008 C# del compilador para inferir correctamente los tipos involucrados al convertir un grupo método a un delegado. @Eric Lippert analiza este comportamiento en su publicación C# 3.0 Return Type Inference Does Not Work On Method Groups.

Si no recuerdo mal, se realizaron algunas mejoras en el nuevo compilador de C# que forma parte de VS2010 que amplía los casos donde es posible la inferencia de grupo de métodos.

Ahora, las reglas para la inferencia de tipo son bastante complicadas, y estoy lejos de ser un experto en este tema. Espero que alguien con un conocimiento real pueda abordar esta pregunta si estoy equivocado.

+0

Su análisis es correcto. –

+0

@Eric Lippert: Gracias por la confirmación. Por cierto, pensé que recuerdo que escribiste sobre las mejoras para escribir inferencias en el último compilador de C#, pero parece que no puedo encontrar ningún artículo en tu blog a tal efecto ... tal vez lo imaginé. – LBushkin

+0

Mencioné que íbamos a arreglarlo, aquí: http://blogs.msdn.com/b/ericlippert/archive/2008/05/28/method-type-inference-changes-part-zero.aspx –

Cuestiones relacionadas