-5

I have program

    public delegate T Transformer<T>(T arg);
    public class Util
    {
        public static void Transform<T>(T[] values, Transformer<T> t)
        {
            for (int i = 0; i < values.Length; i++)
                values[i] = t(values[i]);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int[] values = { 1, 2, 3 };
            Util.Transform(values, Square); // Hook in Square
            foreach (int i in values)
            Console.Write(i + " "); // 1 4 9
            Console.ReadLine();
        }
        static int Square(int x) => x * x;
    }

Why Util.Transform(values, Square) changes values[] array? It is already works like reference variable. I just wanna yo see output result not changing the source array named "values[]".

streamc
  • 676
  • 3
  • 11
  • 27

1 Answers1

1

You can change the method like that:

public class Util
{
    public static T[] Transform<T>(T[] values, Transformer<T> t)
    {
        return values.Select(x => t(x)).ToArray();
    }
}

Then you can call it like

var result = Utils.Transform(values, Square);

If you can't change that method, then you need to copy the array before calling:

var result = values.ToArray();
Utils.Transform(result, Square);
René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • 1
    Just wanted to type something like that. Bottom line, your Transformer method should not update your input, instead, it should create a new array or (List), populate it with transformed values and return. This way you're avoiding side effect you now have. Side effects are not a good practice. Why those values get changed? Well, because you have provided an array of values. You're accessing value directly in memory via its address in an array, not on stack as you might think. This solution is better approach then to create a copy of the original array an pass in. – Nesaje Apr 23 '18 at 15:06
  • I would try but I do not need copying or creating new array – streamc Apr 23 '18 at 15:08
  • Yes, I know that array is reference type. – streamc Apr 23 '18 at 15:09
  • return values.Select(x => t(x)).ToArray(); Why do I need that? This is already outputs array. – streamc Apr 23 '18 at 15:22
  • public static T[] Transform(T[] values, Transformer t) { return values.Select(x => t(x)).ToArray(); for (int i = 0; i < values.Length; i++) values[i] = t(values[i]); } How can I simplify that? – streamc Apr 23 '18 at 15:27
  • @ifooi I did not mention any `for` loop in my code. Why did you mix them together? You should use the method I showed, without the `for` loop. – René Vogt Apr 23 '18 at 15:33
  • @RenéVogt, cause I need to apply square method. – streamc Apr 23 '18 at 15:36
  • @ifooi yes, that is done by the `Select`. – René Vogt Apr 23 '18 at 15:38
  • @RenéVogt, Yes, thanks! It is applied square functtion. I appreciate your solution. Best! – streamc Apr 23 '18 at 15:43