En utilisant les Expressions Lambda arbres avec IEnumerable
J'ai essayé d'en savoir plus sur l'utilisation de Lamba des arbres d'expression et j'ai donc créé un exemple simple. Voici le code, cela fonctionne en LINQPad si le coller dans un programme C#.
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; }
}
Cette résultats dans l'erreur suivante:
Le type des arguments de la méthode 'Système.Linq.Énumérable.Où(Système D'.Les Collections.Génériques.IEnumerable, Système.Func)' ne peut pas être déduit à partir de l'utilisation. Essayez de spécifier le type des arguments explicitement.
Cependant si j'ai juste remplacer la première ligne principale avec ceci:
IEnumerable<User> list = GetUsers().Where(u => u.Name.Contains("a"));
Il fonctionne très bien. Pouvez me dire ce que je fais mal, s'il vous plaît?
OriginalL'auteur Loathian | 2010-03-07
Vous devez vous connecter pour publier un commentaire.
La
Enumerable.Where
méthode prend unFunc<T, bool>
, pas unExpression<Func<T, bool>>
. Vous êtes peut-être confusion avecQueryable.Where
, qui prend une expression comme paramètre... Dans votre cas, vous n'avez pas besoin d'une expression, vous avez juste besoin d'un délégué qui peuvent être exécutées sur chaque élément de la séquence. Le but des expressions de l'est (principalement) pour être analysé et traduit en quelque chose d'autre (SQL par exemple), pour effectuer la requête à l'encontre d'une source de données externeLe fait que les expressions lambda sont considérés comme un délégué ou une arborescence d'expression dépend du contexte. Dans votre code, vous devez déclarer le type de retour que l'Expression, et elle indique au compilateur de considérer l'expression lambda comme une arborescence d'expression, plutôt qu'un fichier exécutable délégué. BTW, l'Expression n'est pas un mot clé, c'est un type de
Oh pinaise ... saisissez pas de mot-clé. Merci Thomas.
J'ai trouvé cet article dans un autre stackoverflow post expliquant les arbres d'expression dans plus de détails. Je comprends maintenant la différence fondamentale entre ce que je faisais et seulement à l'aide de la touche Func je vais fouiller dans des arbres d'expression dans plus de détails. blogs.msdn.com/charlie/archive/2008/01/31/...
OriginalL'auteur Thomas Levesque
Changer le type de retour de
NameContains
deExpression<Func<User, Bool>>
simplementFunc<User, Bool>
. Dans cette situation, il n'y a pas besoin de retourner l'Expression, vous voulez vraiment rendre la compilation délégué. Il y a une différence entre l'expression qui rend le lambda, et le lambda (qui est un délégué).Si vous envoyez un lambda dans une méthode, la méthode peut accepter le lambda soit comme une expression, ou la compilation d'un type délégué, en fonction de ce que vous spécifiez dans les paramètres. Si le nouveau type de paramètre est une Expression, vous pouvez l'envoyer dans quelque chose qui ressemble à un délégué, cependant, si la méthode s'attend à un délégué, vous devez donner un compilé délégué, et non pas simplement une expression. Cela étant dit, vous pouvez aussi faire quelque chose comme:
Qui permettrait de compiler l'expression, et de retourner une
Func<User, Bool>
.OriginalL'auteur David Morton
Lambda expressions peuvent être traités soit comme code (délégués) ou de données (arbres d'expression)
Dans votre exemple, votre tentent de traiter l'expression lambda comme code.
Vous utilisez l'Expression<> déclaration lorsque vous voulez traiter l'expression lambda comme des données.
Pourquoi voudriez-vous faire cela?
Voici une citation du Livre Linq In Action,
" Arbres d'Expression peut être donnée à des outils lors de l'exécution, qui les utilisent pour guide
leur exécution ou de les traduire en quelque chose d'autre, comme SQL dans le cas de
LINQ to SQL".
À l'aide de l'Expression des Arbres permet de prendre la lambda expression et la convertir en données, c'est comment Linq to SQL fonctionne, il faut de l'expression lambda ou des opérateurs de requête ou les expressions de la requête et les convertit en SQL. Bien sûr, vous pouvez afficher et modifier la création de l'expression de l'arbre une fois convertis en sql.
OriginalL'auteur Joe Pitz
Il y a une énorme différence entre l'Expression et le Func<...>, la touche Func est une pure délégué vous pouvez les appeler directement, l'expression est une structure de données contient des informations sur une expression de ce type d'informations sur la lambda expression ou de la Syntaxe Linq (par exemple à Partir de x dans la liste où x.Id = 1 sélectionnez x). L'expression ne peut pas être invoquée directement, il doit être compilé, Expressions est utilisé pour convertir l'expression d'un mode à l'autre comme Lien Vers Sql qui convertit une expression Sql, la meilleure façon de le faire pour changer le type de retour de la NameContains Méthode de Func insted d'expression parce que vous travaillez avec Linq to Objects, mais lors de l'utilisation de Linq to Sql, vous pouvez utiliser à la fois l'Expression ou de la touche func.
OriginalL'auteur Mina W Alphonce