słowo kluczowe delegata a notacja lambda
Po skompilowaniu jest różnica między:
delegate { x = 0; }
I
() => { x = 0 }
?
6 answers
Krótka odpowiedź: Nie.
Dłuższa odpowiedź, która może nie być istotna:
- jeśli przypiszesz lambda do typu delegata (np.
Func
LUBAction
), Otrzymasz anonimowego delegata. - jeśli przypiszesz lambda do typu wyrażenia, otrzymasz drzewo wyrażeń zamiast anonimowego delegata. Drzewo wyrażeń może być następnie skompilowane do anonimowego delegata.
Edytuj: Oto kilka linków do Wyrażenia.
- System.Linq.Ekspresja.Expression (TDelegate) (start tutaj).
- Linq w pamięci z delegatami (np. System.Func) używa systemu .Linq.Enumerable . Linq do SQL (i wszystkiego innego) z wyrażeniami używa systemu .Linq.Queryable . Sprawdź parametry tych metod.
- An Wyjaśnienie ScottGu . W skrócie, Linq in-memory stworzy anonimowe metody rozwiązywania zapytań. LINQ do SQL będzie Utwórz drzewo wyrażeń, które reprezentuje zapytanie, a następnie Przetłumacz to drzewo do T-SQL. Linq to Entities wytworzy drzewo wyrażeń, które reprezentuje zapytanie, a następnie przełoży je na odpowiedni dla platformy SQL.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-26 12:39:57
Podoba mi się odpowiedź Amy, ale myślałem, że będę pedantyczny. Pytanie mówi, "raz jest skompilowany" - co sugeruje, że oba wyrażenia zostały skompilowane. W jaki sposób mogą się skompilować, ale jeden z nich jest konwertowany do delegata, a drugi do drzewa wyrażeń? Jest to trudne - trzeba użyć innej funkcji metod anonimowych, jedynej, której nie współdzielą wyrażenia lambda. Jeśli podasz metodę anonimową bez podawania listy parametrów w ogóle to jest kompatybilny z dowolnym typem delegata zwracającym void i bez żadnych parametrów out
. Uzbrojeni w tę wiedzę, powinniśmy być w stanie skonstruować dwa przeciążenia, aby wyrażenia były całkowicie jednoznaczne, ale bardzo różne.
Możemy użyć sztuczki z parametrami delegata, jeśli zmienimy trochę ciała:
using System;
using System.Linq.Expressions;
public class Test
{
static void Main()
{
int x = 0;
Foo( () => x );
Foo( delegate { return x; } );
}
static void Foo(Func<int, int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
static void Foo(Expression<Func<int>> func)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
Ale czekaj! Możemy rozróżnić te dwa, nawet bez użycia drzew wyrażeń, jeśli jesteśmy wystarczająco sprytni. Poniższy przykład wykorzystuje przeciążenie zasady rozstrzygania sporów (oraz trik dopasowywania anonimowych delegatów)...
using System;
using System.Linq.Expressions;
public class Base
{
public void Foo(Action action)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
public class Derived : Base
{
public void Foo(Action<int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int x = 0;
d.Foo( () => { x = 0; } );
d.Foo( delegate { x = 0; } );
}
}
AUĆ. Pamiętajcie dzieci, za każdym razem, gdy przeciążacie metodę odziedziczoną po klasie podstawowej, mały kotek zaczyna płakać.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-06 18:28:55
W dwóch powyższych przykładach nie ma różnicy, zero.
Wyrażenie:
() => { x = 0 }
Jest wyrażeniem Lambda z ciałem instrukcji, więc nie może być skompilowane jako drzewo wyrażeń. W rzeczywistości nie kompiluje się, ponieważ potrzebuje średnika po 0:
() => { x = 0; } // Lambda statement body
() => x = 0 // Lambda expression body, could be an expression tree.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-24 17:28:24
Amy B ma rację. Zauważ, że używanie drzew wyrażeń może być korzystne. LINQ to SQL sprawdzi drzewo wyrażeń i przekonwertuje je na SQL.
Możesz również wykonywać sztuczki z lamdami i drzewami wyrażeń, aby skutecznie przekazać nazwy członków klasy do frameworka w bezpieczny dla refaktoryzacji sposób. Moq jest tego przykładem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-07 04:24:42
Istnieje różnica
Przykład:
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(delegate
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
I zamieniam na lambda: (błąd)
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(()=>
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-03 07:54:29
Kilka podstaw tutaj.
Jest to metoda anonimowa
(string testString) => { Console.WriteLine(testString); };
Ponieważ Metody anonimowe nie mają nazw, potrzebujemy delegata, do którego możemy przypisać obie te metody lub wyrażenia. np.
delegate void PrintTestString(string testString); // declare a delegate
PrintTestString print = (string testString) => { Console.WriteLine(testString); };
print();
To samo dotyczy wyrażenia lambda. Zazwyczaj potrzebujemy delegata do ich użycia
s => s.Age > someValue && s.Age < someValue // will return true/false
Możemy użyć delegata func do użycia tego wyrażenia.
Func< Student,bool> checkStudentAge = s => s.Age > someValue && s.Age < someValue ;
bool result = checkStudentAge ( Student Object);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-26 00:46:39