Comment puis-je assigner un Func conditionnellement entre les lambda en utilisant l’opérateur ternaire conditionnel?

Généralement, lorsque vous utilisez l’opérateur conditionnel, voici la syntaxe:

int x = 6; int y = x == 6 ? 5 : 9; 

Rien d’extraordinaire, plutôt simple.

Maintenant, essayons de l’utiliser lors de l’atsortingbution d’un Lambda à un type Func. Laisse-moi expliquer:

 Func predicate = id == null ? p => p.EmployeeID == null : p => p.EmployeeID == id; 

C’est la même syntaxe, et devrait fonctionner? Droite? Pour une raison qui ne le fait pas. Le compilateur donne ce joli message crypté:

Erreur 1 Le type d’expression conditionnelle ne peut pas être déterminé car il n’y a pas de conversion implicite entre l’expression lambda et l’expression lambda

Je suis ensuite allé de l’avant et j’ai changé la syntaxe pour que cela fonctionne:

 Func predicate = id == null ? predicate = p => p.EmployeeID == null : predicate = p => p.EmployeeID == id; 

Je suis juste curieux de savoir pourquoi cela ne fonctionne pas dans le premier sens?

(Note de côté: j’ai fini par ne plus avoir besoin de ce code, car j’ai découvert que lorsque vous compariez une valeur int à null, vous utilisiez simplement object.Equals)

Vous pouvez convertir une expression lambda en un type de délégué cible spécifique, mais pour déterminer le type de l’expression conditionnelle, le compilateur doit connaître le type de chacun des deuxième et troisième opérandes. Bien qu’ils ne soient que “lambda expression”, il n’y a pas de conversion de l’un à l’autre, donc le compilateur ne peut rien faire d’utile.

Je ne suggérerais pas d’utiliser une tâche, cependant – une dissortingbution est plus évidente:

 Func predicate = id == null ? (Func) (p => p.EmployeeID == null) : p => p.EmployeeID == id; 

Notez que vous devez uniquement le fournir pour un opérande, afin que le compilateur puisse effectuer la conversion à partir de l’autre expression lambda.

Le compilateur C # ne peut pas déduire le type de l’expression lambda créée, car il traite d’abord le ternaire, puis l’affectation. vous pourriez aussi faire:

 Func predicate = id == null ? new Func(p => p.EmployeeID == null) : new Func(p => p.EmployeeID == id); 

mais ça craint, vous pouvez aussi essayer

 Func predicate = id == null ? (Order p) => p.EmployeeID == null : (Order p) => p.EmployeeID == id; 

Permettez-moi d’avoir mon propre exemple car j’ai eu le même problème (avec l’espoir que cet exemple soit utile pour les autres):

Ma méthode Find est une méthode générique qui obtient l’ Expression> tant que prédicat et donne en sortie List .
Je voulais trouver des pays, mais j’ai besoin de tous si la liste de langues était vide et la liste filtrée, si la liste de langues était remplie. J’ai d’abord utilisé le code ci-dessous:

 var counsortinges= Find(languages.Any() ? (country => languages.Contains(country.Language)) : (country => true)); 

Mais exactement, je reçois l’erreur: there is no implicit conversion between lambda expression and lambda expression.

Le problème était que, nous avons juste deux expressions lambda ici, et rien d’autre, par exemple, qu’est-ce que country => true exactement? Nous devons déterminer le type d’ au moins une des expressions lambda . Si seulement une des expressions est déterminée, alors l’erreur sera omise. Mais pour rendre le code plus lisible, j’ai extrait les deux expressions lambda et utilisé la variable à la place, comme ci-dessous:

  Expression> getAllPredicate = country => true; Expression> getCounsortingesByLanguagePredicate = country => languages.Contains(country.Language); var counsortinges= Find(languages.Any() ? getCounsortingesByLanguagePredicate : getAllPredicate); 

J’insiste sur le fait que si je viens de déterminer un type d’expression, l’erreur sera corrigée.