0

I wanted to initialize an array of functions from a double Convert(int index, int input) function where I pass the index of the element in the array like this:

var myfunctions= new Func<ushort, double>[10];
for (int i=0; i<10; i++)
{
   myfunctions[i] = new Func<ushort, double>(x_in => {return Convert(i, in);});
}

but that doesn't work since any call to an element x of myfunctions array myfunctions[x](myVal) will do this equivalent call Convert(10, myVal) and x is always = 10 (last value of i in the initialisation loop)

So I had to code this ugly thing to make it work :

var myfunctions= new Func<ushort, double>[10];
myfunctions[0] = new Func<ushort, double>(x_in => {return Convert(0, in);});
myfunctions[1] = new Func<ushort, double>(x_in => {return Convert(1, in);});
...
myfunctions[9] = new Func<ushort, double>(x_in => {return Convert(9, in);});

Any suggestions ? Thanks

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • A lambda captures a reference to any external variables, not a copy of their value. Make a local copy inside, the lambda, eg: `x_in => {var idx=i;return Convert(idx, x_in);}` – Panagiotis Kanavos Jul 07 '22 at 08:11
  • @PanagiotisKanavos How does your code fix that problem? Your "local" copy is not local as you meant it. Your sample does also reference the wrong value. The local copy has to be created in the body of the function. The lambda should only be `x_in => Convert(idx, x_in)`. [DEMO](https://dotnetfiddle.net/fM99UJ) – Sebastian Schumann Jul 07 '22 at 08:22
  • Sorry, it doesn't work – Yannick Favre Jul 07 '22 at 08:23
  • @SebastianSchumann you mean the body of the loop. I added this as a quick comment to explain the duplicate without actually testing it. So it should be `var idx=i; myfunctions[i] = new Func(x_in => {return Convert(idx, x_in);});` – Panagiotis Kanavos Jul 07 '22 at 08:25
  • @PanagiotisKanavos Yes that's what I mean. Here is a working sample: [DEMO](https://dotnetfiddle.net/kZbSn2) – Sebastian Schumann Jul 07 '22 at 08:28
  • Or `myFunctions=Enumerable.Range(0,10).Select(i=>new Func(x_in => Convert(i, x_in))).ToArray();` – Panagiotis Kanavos Jul 07 '22 at 08:31
  • I managed to make it work by doing a copy of the index in the loop: ```for (int i=0; i<10; i++) { var idx = i; myfunctions[i] = new Func(x_in => {return Convert(idx, in);}); }``` – Yannick Favre Jul 07 '22 at 08:40

0 Answers0