2016-07-13 2 views
17

In dieser Frage, wenn ich den Compiler erwähne, beziehe ich mich eigentlich auf den Roslyn Compiler. Das Problem tritt auf, wenn IntelliSense verwandt wird, von dem angenommen wird, dass es derselbe Compiler ist.Offene generische Argumente können nicht aus der Verwendung abgeleitet werden

Zur Demonstration und Vollständigkeit werden die folgenden Klassen (Visual Studio 2015 mit C# 6.0 und .NET 4.6.1 verwenden):

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> { } 

Siehe, die folgenden Erweiterungsmethode:

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

Der Compiler ist in der Lage, es zu schließen, während wie dieser raubend:

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

Auch diese überladene Erweiterungsmethode siehe:

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

Der Compiler ist NICHT Lage T1 zu schließen, wenn es wie folgt eingeben:

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

Dieses Screenshot Beispiel wird eher beschreiben, was ich meine mit nicht in der Lage zu schließen:
enter image description here

Auch Nachricht Ich erhalte diese Störung, wenn über die Erweiterungsmethode mit meiner Maus schweben (ich die < und > Zeichen mit [ und ] jeweils ersetzt habe, weil nicht die in Stackoverflow einem Zitat formatiert):

The type arguments for method 'FooBar[T1,T2](this Helper[IEnumerable[T1]], Expression[Func[T1, IEnumerable[T2]]])' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Aber wenn es manuell wie folgt durchführen:

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

der Compiler happ ist y.

Warum kann der Compiler/IntelliSense (oder die Funktion zur automatischen Vervollständigung von Visual Studio) herauszufinden T1 und will, dass ich die Typargumente explizit angeben, wenn ich Eingabe beginnen?

Hinweis, dass, wenn ich IEnumerable<> überall in meinen Beispielen weglassen, die Eingabe der Compiler glücklich alles ableiten kann, während. Der Compiler ist auch glücklich, nachdem Sie l => l.B manuell eingeben. Er weiß dann T1 ist A, so dass Sie das letzte Argument mit die Hilfe von IntelliSense ausdrücken können.

+9

Wenn Sie sagen, "Compiler kann nicht schließen, dass T1 A ist", meinen Sie eigentlich die automatische Vervollständigung der IDE, richtig? –

+0

@TimPohlmann Ich habe meine Frage bearbeitet, den irrelevanten Teil verdeckt. Und ja, ich meine, die IntelliSense-Funktion zur automatischen Vervollständigung funktioniert in diesem sehr speziellen Moment nicht. – QuantumHive

+2

Eine der Ideen hinter dem gesamten Roslyn-Projekt war, einen einzigen Compiler zu haben, der den Code kompilierte und in IntelliSense lief. In gewisser Weise unterscheidet sich IntelliSense jedoch etwas von der Kompilierung (ich denke, dass mehr Informationen benötigt werden).So haben wir immer noch einige Fälle, in denen IntelliSense nur unsere kündigt, während Code noch glücklich kompiliert :-( – Steven

Antwort

4

Wenn ich Sie richtig verstanden habe, alles für mich arbeitet in VS2013 wie erwartet:

Ihr erster Fall:

Ihr zweiter Fall:

Ich fange an, dieeinzugebenund IntelliSense zeigt mir, dass l eine Eigenschaft B hat, die verwendet werden kann. Also, wenn ich richtig und es folgert richtig in VS2013 während es nicht in VS2015 nicht schließen, dann ist es auf jeden Fall ein Fehler in VS2015 IntelliSense, die an Microsoft gemeldet werden können.

2

Ich habe deine Frage interessant gefunden und seit ich VS 2015 benutze, dachte ich, ich könnte es auch versuchen. Ich habe den gleichen Fehler wie du, also kann es ein VS-Fehler sein, da er in anderen Versionen korrekt funktioniert.

Hier ist mein Fehler:

enter image description here

Und ich bekomme auch keine Vorschläge auf CTRL + SPACE.

EDIT:

Ein ähnlicher Fehler kann here zu sehen.

Also, da in älteren Versionen von VS dies funktioniert, ist dies der Grund, warum es als ein Fehler betrachtet werden kann.

2

Wie gesagt ich die same problem. hatte (Und here ist der Bug-Report)
Es ist nicht auf Ausdrücke oder IEnumerable verwandt.
Hier ist ein vereinfachtes Beispiel

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; } 
    } 
} 

ich, dass nur bemerkt, wenn Sie das dritte Argument aus dem Verfahren entfernen es funktioniert !!!

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; } 
    } 
} 

Also, wenn Sie Glück haben Sie vielleicht in der Lage sein, Ihr aktuelles Beispiel zu beheben, indem Sie Parameter zwicken.
Wenn nicht, müssen Sie nur auf MS warten, um es zu beheben ...

Verwandte Themen