11
votes

Comment l'expression multi-paramètres LINQ initialise-t-elle leur paramètre?

dans ce Post La solution au problème est la suivante:

Liste.aughle ((élément, index) => index

Le concept de multi-paramètres (c.-à-d. (élément, index) ) est un peu déroutant pour moi et je ne connais pas le mot correct pour réduire mes résultats Google. Donc, 1) Qu'est-ce que cela dit? Et plus important encore, 2) Comment la variable non énonciable est-elle initialisée? Dans ce cas, comment est compilé compilé sous forme d'int et initialisé à 0?

merci.


1 commentaires

Notez que vous avez eu élément et index inversé; On dirait que cela a été corrigé par une édition.


3 Réponses :


13
votes

Les expressions Lambda ont diverses options de syntaxe: xxx

la subtilité ici est que a une surcharge qui accepte un func , représentant la valeur et index respectivement (et renvoyant le bool pour le match). Donc, c'est le implémentation qui fournit l'index - quelque chose comme: xxx


2 commentaires

Y a-t-il un moyen d'initialiser l'index à autre chose que 0?


@Edward dans la mise en œuvre du cœur? non. Mais vous pouvez simplement ajouter un numéro fixe à index dans l'expression, i.e. Liste [index + offset] . Dans une implémentation personnalisée, vous pouvez faire tout ce que vous voulez, mais je ne suis pas sûr de la sagesse / besoin / etc.



4
votes

Lorsque vous utilisez LINQ, rappelez-vous que vous passez une méthode déléguée au où code> méthode. La surcharge particulière de où code> que vous appelez prend une méthode avec Signature Func code> et appellera cette méthode pour chaque élément de la liste code>. En interne, cette méthode particulière consiste à tenir compte pour chaque élément itéré et appelant le délégué fourni à l'aide de cette valeur en tant que deuxième paramètre:

var result=suppliedDelegate(item,count)


1 commentaires

Ceci s'applique également à Sélectionnez la méthode à Linq



2
votes

Cette réponse est un peu plus technique ... rappelez-vous que les Lambdas sont simplement des raccourcis syntatiques aux délégués anonymes (qui sont des méthodes anonymes). EDIT: strong> Ils peuvent aussi être des arbres d'expression en fonction de la signature du où code> (voir le commentaire de Marc).

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
    int index = 0;

    foreach (TSource item in source)
    {
        if (predicate(index, source))
             yield return item;

        index++;
    }
}


2 commentaires

"N'oubliez pas que les lambdas sont simplement des raccourcis syntatiques aux délégués anonymes" n'est pas vrai; Ils peuvent des méthodes anonymes, mais ils pourraient aussi être des arbres d'expression. Il n'ya aucun moyen de prédire ce que vous ne connaissez que si vous connaissez le Signature, qui est généralement déterminé par la source de données, c'est-à-dire de la liste est dans le premier exemple de code dans votre message.


@MARC: Tu as raison. Qu'il s'agisse d'un arbre d'expression ou d'une méthode anonyme, les comparaisons sont toujours identiques. Le résultat est donc identique. Les arbres d'expression sont-ils généralement plus rapides puisque l'arbre entier peut devenir un délégué (moins sur la pile, etc.)? Et bien sûr, si vous avez affaire à Linq à SQL, cela finit par devenir SQL, pas nécessairement un délégué.