c# .net generics visual-studio-2015 roslyn

c# - Los argumentos de tipo genérico abierto no se pueden inferir del uso



.net generics (3)

En esta pregunta, cuando menciono el compilador, me refiero al compilador de Roslyn . El problema surge cuando se usa IntelliSense , que se presume que es el mismo compilador.

Para fines de demostración y exhaustividad, se utilizan las siguientes clases ( utilizando Visual Studio 2015 con C # 6.0 y .NET 4.6.1 ):

public class A { public IEnumerable<B> B { get; set; } } public class B { public IEnumerable<C> C { get; set; } } public class C { } public class Helper<T> { }

He aquí el siguiente método de extensión:

public static void FooBar<T1, T2>( this Helper<IEnumerable<T1>> helper, Expression<Func<T1, IEnumerable<T2>>> expression) { ... }

El compilador es capaz de inferirlo consumiendo así:

Helper<IEnumerable<B>> helper = ...; helper.FooBar(l => l.C); //T1 is B and T2 is C

También he aquí este método de extensión sobrecargada:

public static void FooBar<T1, T2, T3>( this Helper<T1> helper, Expression<Func<T1, IEnumerable<T2>>> expression1, Expression<Func<T2, IEnumerable<T3>>> expression2) { ... }

El compilador NO es capaz de inferir T1 cuando lo escribe así:

Helper<A> helper = ...; helper.FooBar(l => l. //compiler/IntelliSense cannot infer that T1 is A

Este ejemplo de captura de pantalla describirá más de lo que quiero decir con que no puedo inferir :

También recibo este mensaje de error al desplazar el mouse sobre el método de extensión ( he reemplazado los caracteres < y > con [ y ] respectivamente, porque StackOverflow no puede formatearlos en una cita ):

Los argumentos de tipo para el método ''FooBar [T1, T2] (este Ayudante [IEnumerable [T1]], Expresión [Func [T1, IEnumerable [T2]]])'' no se pueden deducir del uso. Trate de especificar los argumentos de tipo explícitamente.

Pero al completarlo manualmente así:

helper.FooBar(l => l.B, l => l.C); //compiler infers that T1 is A, T2 is B and T3 is C

el compilador es feliz

¿Por qué el compilador / IntelliSense ( o la función de autocompletar de Visual Studio ) no puede entender T1 y quiere que especifique explícitamente los argumentos de tipo cuando empiezo a escribir?

Tenga en cuenta que si IEnumerable<> en todas partes en mis ejemplos, el compilador puede inferir felizmente todo mientras escribe.
El compilador también está contento después de escribir manualmente l => lB Entonces sabe que T1 es A , por lo que puede expresar el último argumento con la ayuda de IntelliSense.


Como dije, tuve el mismo problema. (Y connect.microsoft.com/VisualStudio/feedback/details/2263258/… está el informe de error)
No está relacionado con Expresiones o IEnumerable.
Aquí hay un ejemplo simplificado

using System; namespace ConsoleApplicationExpressionTree { public static class Extentions { static void Main() { } static void AMethod(string[] args) { SetValue(new Customer(), e => e.Name /*type here */, "TheName"); } public static void SetValue<TEntity, TProperty>(TEntity instance, Func<TEntity, TProperty> expression, TProperty newValue) { } } public class Customer { public string Name { get; set; } public int Age { get; set; } } }

¡Acabo de notar que si eliminas el tercer argumento del método funciona!

using System; namespace ConsoleApplicationExpressionTree { public static class Extentions { static void Main() { } static void AMethod(string[] args) { SetValue(new Customer(), e => e.Name /*type here */); } public static void SetValue<TEntity, TProperty>(TEntity instance, Func<TEntity, TProperty> expression) { } } public class Customer { public string Name { get; set; } public int Age { get; set; } } }

Entonces, si tiene mucha suerte, podría corregir su ejemplo actual al ajustar sus parámetros.
Si no, solo tendrás que esperar a que MS lo arregle ...


Encontré su pregunta interesante y, como estoy usando VS 2015, pensé que también podía intentarlo. Recibí el mismo error que usted, por lo que supongo que puede ser un error de VS, ya que en otras versiones funciona correctamente.

Aquí está mi error:

Y también recibo No hay sugerencias sobre CTRL + ESPACIO.

EDITAR:

Un error similar se puede ver aquí .

Entonces, ya que en versiones anteriores de VS esto funciona, entonces esta es la razón por la que puede considerarse un error.


Si te entendí correctamente, todo funciona como se esperaba para mí en VS2013 :

Tu primer caso:

Tu segundo caso:

Estoy empezando a escribir el l. e IntelliSense me muestra que l tiene una propiedad B que se puede usar. Entonces, si tengo razón y se infiere correctamente en VS2013 mientras que no se infiere en VS2015 , entonces definitivamente es un error en el IntelliSense VS2015 que se puede informar a Microsoft.