Mithilfe von Lambda-Ausdrücken Bäume mit IEnumerable
Ich habe versucht zu lernen, mehr über die Verwendung von Lamba-Ausdruck Bäume und so erstellte ich ein einfaches Beispiel. Hier ist der code, das funktioniert in LINQPad, wenn eingefügt, wie ein C# - Programm.
void Main()
{
IEnumerable<User> list = GetUsers().Where(NameContains("a"));
list.Dump("Users");
}
//Methods
public IEnumerable<User> GetUsers()
{
yield return new User{Name = "andrew"};
yield return new User{Name = "rob"};
yield return new User{Name = "chris"};
yield return new User{Name = "ryan"};
}
public Expression<Func<User, bool>> NameContains(string namePart)
{
return u => u.Name.Contains(namePart);
}
//Classes
public class User
{
public string Name { get; set; }
}
Diese Ergebnisse in der folgenden Fehlermeldung:
Der Typ der Argumente für die Methode 'System.Linq -.Enumerable.Wo(System.Sammlungen.Generisches.IEnumerable, System.Func)' kann nicht abgeleitet werden aus der Nutzung. Versuchen Sie, den Typ der Argumente explizit.
Allerdings, wenn ich ersetzen Sie einfach die erste Zeile in main mit dabei:
IEnumerable<User> list = GetUsers().Where(u => u.Name.Contains("a"));
Funktioniert es einwandfrei. Kann mir sagen was ich falsch mache, bitte?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
Enumerable.Where
Methode nimmt einenFunc<T, bool>
, nicht einExpression<Func<T, bool>>
. Vielleicht sind Sie verwirrend, mitQueryable.Where
, die nicht nehmen, einen Ausdruck als parameter... In Ihrem Fall brauchen Sie nicht einen Ausdruck, Sie brauchen nur ein Delegierter, die ausgeführt werden können gegen jedes Element in der Sequenz. Der Zweck der Ausdrücke ist (meist) werden analysiert und übersetzt in etwas anderes (für SQL Instanz), um die Abfrage für eine externe DatenquelleÄndern Sie den Rückgabetyp der
NameContains
ausExpression<Func<User, Bool>>
einfachFunc<User, Bool>
. In dieser situation, es gibt keine Notwendigkeit zur Rückkehr der Ausdruck, den Sie wirklich wollen, um die Rückkehr der kompilierten delegieren. Es gibt einen Unterschied zwischen dem Ausdruck, der die lambda und lambda (das ist ein delegieren) selbst.Wenn Sie senden einen lambda-Ausdruck in eine Methode kann die Methode akzeptieren, die lambda-entweder als Ausdruck, oder als eine kompilierte delegate-Typ, je nachdem, was Sie, in angeben der Parameter. Wenn die eingehenden parameter Typ ist ein Ausdruck, den Sie senden können, in etwas, das aussieht wie eine Delegierte, jedoch, wenn die Methode erwartet einen Delegaten, die Sie haben, um ihm eine kompilierte delegieren, nicht einfach ein Ausdruck. , Die being said, Sie können auch etwas tun:
Dem zusammenstellen würde der Ausdruck, und geben Sie einen
Func<User, Bool>
.Lambda-Ausdrücke können behandelt werden, entweder als code (Delegierte) oder als Daten (expression trees)
In deinem Beispiel Ihren versuchen zur Behandlung der lambda-Ausdruck als code.
Verwenden Sie den Ausdruck<> Erklärung, wenn Sie wollen, um die Behandlung von lambda-Ausdruck als Daten.
Warum würden Sie wollen, dies zu tun?
Hier ist ein Zitat aus dem Buch von Linq In Action,
" Ausdruck Bäume können gegeben werden, um Werkzeuge zur Laufzeit, was nutzen Sie, um guide
Ihre Ausführung oder übersetzen Sie in etwas anderes, wie SQL in die Falle
LINQ to SQL".
Mithilfe von Expression Trees ermöglicht es Ihnen, den lambda-Ausdruck und wandelt es in Daten, dies ist, wie Sie mit Linq to SQL arbeiten, es ist der lambda-Ausdruck oder-Abfrage-Operatoren oder query-Ausdrücke und konvertiert Sie in SQL. Sie können natürlich das anzeigen und ändern der erstellte Ausdruck ein Baum nach der Umstellung auf sql.
Ist es ein riesiger Unterschied zwischen Ausdruck und Func<...> die Func ist ein reines delegieren, Sie können es aufrufen, direkt, der Ausdruck ist eine Daten-Struktur enthält Informationen über einen Ausdruck wie Informationen über lambda-Ausdruck oder mit Linq-Syntax (z.B. Von x in der Liste, wo x ist.Id = 1 select x). Der Ausdruck kann nicht direkt angesprochen werden, es muss zuerst kompiliert werden, Ausdrücke verwendet, ist zum konvertieren der Ausdruck von einem Weg zum anderen, wie die Verbindung Zu Sql, die konvertiert einen Ausdruck, um Sql-Anweisungen, der beste Weg, dies zu tun, ändern Sie den Rückgabetyp der NameContains Methode Func insted Ausdruck cuz Sie sind die Arbeit mit Linq To Objects, nur wenn Sie mit Linq To Sql können Sie sowohl Ausdruck oder func.