Aktion wie FuncTResult?

7

Ich bin auf eine Situation gestoßen, in der ich etwas Wissen brauche.

Unten ist der Code:

%Vor%

Mein Verständnis von Action war, dass es mit einem Delegaten übereinstimmt, der keinen Parameter akzeptiert und nichts zurückgibt.

Und für Func<int> , dass es mit einem Delegaten übereinstimmt, der keinen Parameter akzeptiert und ein int zurückgibt.

DoSomething Methode gibt eine ganze Zahl zurück, daher meine Frage: () => DoSomething() ist ein Delegat, das ein int zurückgibt. Func funktioniert wie erwartet, Action jedoch nicht. Warum? Was verstehe ich hier nicht?

Der Code wird kompiliert und läuft ordnungsgemäß, beide Ausgaben i am called . Was ich wissen möchte, ist, warum Action action = () => DoSomething(); ist kein Fehler Kompilierzeit?

    
singsuyash 22.10.2015, 14:33
quelle

5 Antworten

10
  

Was ich wissen möchte ist, dass Action action = () => DoSomething(); kein Kompilierzeitfehler ist?

Es kompiliert, weil Sie einen Lambda-Ausdruck haben, der die Methode aufruft, aber das Ergebnis ignoriert. Sie können keine Methodengruppenkonvertierung verwenden, z. B.

%Vor%

(Die Konvertierung der gleichen Methodengruppe für Func<Action, int> ist in Ordnung.)

Aber stattdessen machst du etwas mehr so:

%Vor%     
Jon Skeet 22.10.2015, 14:44
quelle
8

Action action = () => DoSomething(); ist äquivalent zu Action action = () => { DoSomething(); };

Func<int> func = () => DoSomething(); ist äquivalent zu Func<int> func = () => { return DoSomething(); };

    
Alexander 22.10.2015 14:43
quelle
3

Der C # -Compiler ist schlau genug, um herauszufinden, dass () => DoSomething() je nach Kontext unterschiedliche Dinge bedeutet. Wenn Sie eine Action Variable zuweisen, wird eine Action (anstelle von Func<int> ) generiert, die das Rückgabeergebnis von DoSomething() ignoriert.

    
Dmytro Shevchenko 22.10.2015 14:40
quelle
1
  

DoSomething Methode gibt eine ganze Zahl zurück, daher meine Frage: (x) => DoSomething(x) ist ein Delegat, der ein object akzeptiert und ein int zurückgibt. Func funktioniert wie erwartet, Action jedoch nicht. Warum? Was verstehe ich hier nicht?

Der Fehler in Ihrem Verständnis ist hier richtig: (x) => DoSomething(x) hat keinen Typ. Es ist nichts. Der Compiler benötigt einen Kontext, um herauszufinden, um welchen Typ es sich handelt. Für sich genommen ist ein Lambda nichts Besonderes, deshalb können Sie var nicht mit einem Lambda-Ausdruck verwenden: Der Compiler weiß nicht, welchen Typ das Lambda haben soll, damit er den Typ nicht ableiten kann.

Zum Beispiel könnte (x) => DoSomething(x) auch ein Ausdrucksbaum sein:

%Vor%

Sie sagen dem Compiler also, wie Sie ein Lambda basierend auf dem Typ, dem Sie es zuweisen, interpretieren.

    
Kyle 22.10.2015 14:50
quelle
0

Ihr ganzes Verständnis ist richtig. Es ist Ihre spezifische Verwendung, die zu Verwirrung führen kann. Sowohl Func als auch Action sind in Ordnung. Beide Anrufe sind in Ordnung. Ich denke, der Fall, der Ihr Problem beleuchten könnte, ist:

var x = action(5); // NOT ok var y = func(5); // ok

Ihr Beispielcode ignoriert nur den Rückgabewert, weshalb es so aussieht, als wären sie gleich. Nicht anders als

void Foo1(int x) { return; } void Foo2(int x) { return 1; } Foo1(5); Foo2(5);

    
Todd Sprang 22.10.2015 14:46
quelle

Tags und Links