185 votes

Impossible d'utiliser un paramètre ref ou out dans les expressions lambda

Pourquoi ne peut-on pas utiliser un paramètre ref ou out dans une expression lambda ?

J'ai rencontré cette erreur aujourd'hui et j'ai trouvé une solution de contournement mais j'étais quand même curieux de savoir pourquoi c'est une erreur de compilation.

CS1628: Impossible d'utiliser le paramètre 'parameter' en ref ou out à l'intérieur d'une méthode anonyme, d'une expression lambda ou d'une expression de requête

Voici un exemple simple :

private void Foo()
{
    int value;
    Bar(out value);
}

private void Bar(out int value)
{
    value = 3;
    int[] array = { 1, 2, 3, 4, 5 };
    int newValue = array.Where(a => a == value).First();
}

0 votes

Il s'agit d'itérateurs, mais une grande partie du raisonnement dans ce post (également par Eric Lippert — il est bien membre de l'équipe de conception du langage) s'applique également aux lambdas: <blogs.msdn.com/ericlippert/archive/2009/07/13/…>

18 votes

Puis-je demander quelle était la solution de contournement que vous aviez trouvée ?

3 votes

Vous pouvez simplement déclarer une variable normale locale et travailler avec celle-ci, puis attribuer le résultat à la valeur par la suite... Ajoutez une instruction var tempValue = valeur; puis travaillez avec tempValue.

1voto

Tobias Knauss Points 63

Vous ne pouvez pas utiliser un paramètre out directement dans une expression lambda. La raison pour laquelle vous ne pouvez pas le faire est expliquée dans les autres réponses.

Solution de contournement

Mais vous pouvez utiliser une variable temporaire locale pour la fonction interne et, après l'exécution de la fonction interne, assigner la valeur de sortie de la fonction interne à la valeur de sortie de la fonction externe :

private static int OuterFunc(int i_param1, out int o_param2)
{
  int param2 = 0;
  var del = () => InnerFunc(i_param1, out param2);
  int result = del();

  o_param2 = param2;
  return result;
}

private static int InnerFunc(int i_param1, out int o_param2)
{
  o_param2 = i_param1;
  return i_param1;
}

private static void Main(string[] args)
{
  int result = OuterFunc(123, out int param2);
  Console.WriteLine(result);  // affiche '123'
  Console.WriteLine(param2);  // affiche '123'
}

Veuillez noter
La question a été créée en 2009. Ma réponse a été créée en 2023 en utilisant C#10 et .NET 6. Je ne sais pas si cette réponse fonctionnait également en 2009, ce qui signifie que le code ici pourrait dépendre des améliorations apportées à C# et .NET qui ont pu être faites entre-temps.

0voto

笑先生 Points 31

Je vais vous donner un autre exemple.

Description

Le code ci-dessous va générer cette erreur. Parce que le changement apporté par l'expression lambda (i)=>{...} ne fonctionne que dans la fonction test.

static void test(out System.Drawing.Image[] bitmaps)
{
    int count = 10;

    bitmaps = new System.Drawing.Image[count];
    Parallel.For(0, count, (i) =>
    {
        bitmaps[i] = System.Drawing.Image.FromFile("2.bmp");
    });
}

Solution

Donc, si vous enlevez out du paramètre, cela fonctionne.

static void test(System.Drawing.Image[] bitmaps)
{
    int count = 10;

    bitmaps = new System.Drawing.Image[count];
    Parallel.For(0, count, (i) =>
    {
        bitmaps[i] = System.Drawing.Image.FromFile("2.bmp");
    });
}

Si vous avez vraiment besoin de out, ne modifiez pas le paramètre dans l'expression lambda directement. Utilisez plutôt une variable temporaire s'il vous plaît.

static void test(out System.Drawing.Image[] bitmaps)
{
    int count = 10;

    System.Drawing.Image[] bitmapsTemp = new System.Drawing.Image[count];
    Parallel.For(0, count, (i) =>
    {
        bitmapsTemp[i] = System.Drawing.Image.FromFile("2.bmp");
    });
    bitmaps = bitmapsTemp;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X