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:
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.
Wenn Sie sagen, "Compiler kann nicht schließen, dass T1 A ist", meinen Sie eigentlich die automatische Vervollständigung der IDE, richtig? –
@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
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