Ich habe folgendes Beispiel.Warum verursacht dies den Fehler CS4011: Argumente vom Typ können nicht aus der Verwendung abgeleitet werden?
class Program {
static void Main(string[] args) {
var varc = new C();
// Error CS0411
var varf1b = varc.F1(t => new { City = t.City }, (t, v) => v + t.Status, (g, a) => new { City = g.City, Bigstatus = a });
// compiles OK
var varf1a = varc.F1(t => new { City = t.City }, (C t, int v) => v + t.Status, (g, a) => new { City = g.City, Bigstatus = a });
// now replace varc by an anonymous class -- how to solve it now?
var varanon = new { };
}
}
public class C {
public string City;
public int Status;
}
public static class X {
public static T1 F1<T2, T3, T4, T1>(
this T2 s,
Func<T2, T3> g,
Func<T2, T4, T4> a,
Func<T3, T4, T1> r)
where T2 : class where T3 : class where T1 : class {
return null;
}
}
Der erste Aufruf löst den Fehler CS0411 aus. Ich kann das nicht mit der üblichen Methode beheben, die die Typargumente hinzufügt, weil sie anonyme Typen verwendet. Glücklicherweise scheint das Hinzufügen von Typen zu einem der Lambdas ausreichend zu sein, um den Compiler glücklich zu machen.
Warum ist das? Was genau macht das erste Beispiel fehl und das zweite gelingt?
Und zweitens gibt es eine Möglichkeit, den Funktionsaufruf zu schreiben, so wird dies nicht passieren, und der Benutzer ist nicht konfrontiert mit dem Einfügen von Typen in das Lambda?
Ja, andere haben ähnliche Fragen gestellt, aber was hier einzigartig ist, ist (a) die Verwendung von anonymen Typen (b) das Update durch Hinzufügen von Typen zum Lambda.
Editiert: das Problem mit der Lösung gegeben ist, dass es nicht mit anonymen Klassen verwendet werden kann, weil es keine Typanmerkung möglich ist.
Sieh es so, du erwartest, dass der Compiler weiß, dass 'v' vom Typ' int' ist. Aber warum sollte es möglich sein? 'T4' könnte leicht' long', 'double',' dezimal' oder jeder andere Typ sein, der den Additionsoperator mit ganzen Zahlen überlädt. –
@JeffMercado: Nein, das ist es nicht. Der Compiler ist nicht an der Form des Ausdrucks interessiert: Sie können ihn durch irgendetwas ersetzen (gültig), ohne den Fehler zu ändern. –
Mein Punkt ist, dass der Compiler nicht zu weit gehen wird, um zu versuchen, die Typen für Sie zu bestimmen, zumindest nicht so weit wie andere Sprachen.Und selbst wenn es versuchen würde, würde es nicht gelingen, weil die Wahl mehrdeutig wäre. Es wird nur die Typen verwenden, von denen es vollständig bekannt war. Sie können keine Informationen über die Eingabetypen bereitstellen, aber die Ausgabetypen und alles, was Sie angeben, ist, dass 'T4' das Ergebnis des Hinzufügens eines' T4' mit einem 'int' sein könnte, was nicht genug Information ist. –