Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

There is a way to pass-by-reference using variable parameters in C#?

I would like to have a function that modifies some variable list of parameters but they are all value types (int, string). There is a way to make the params keyword work with ref keyword or something close to that?

public void funcParams(params object[] list)
{
   /* Make something here to change 'a', 'b' and 'c' */
}

public void testParams()
{
    int a = 1, b = 2, c = 3;

    funcParams(a, b, c);
}

The problem is, I'm trying to make my life easier making a method that modifies the object fields. I'm doing some dynamic code generation using Cecil and I'm trying to avoid writing too much IL generated code.

To simplify I would like to pass the list of fields by reference I need to change to a function that changes them instead of changing them by generating the respective IL. Some of the parameters are nullable and make the code generation a little more painful. Making some overload methods instead of params won't be much useful in this case.

like image 624
Edwin Jarvis Avatar asked Dec 07 '22 08:12

Edwin Jarvis


2 Answers

Well, you could declare a few overloads, i.e.

public void FuncParams(ref int a) {...}
public void FuncParams(ref int a, ref int b) {...}

etc

Otherwise, you'll have to read back from the array (as params really means "implicit array"):

object[] args = {1,2,3};
funcParams(args);
Console.WriteLine(args[0]); // updated
Console.WriteLine(args[1]); // updated
Console.WriteLine(args[2]); // updated

(of course, if it only accepts ints, it would be better to use an int[] throughout)

like image 192
Marc Gravell Avatar answered May 19 '23 19:05

Marc Gravell


Yes. It is possible.

However, the resulting code is "unsafe" which makes it unverifiable.

That may or may not be an issue depending on your requirements.

In any case, here is the code:

using System;

namespace unsafeTest
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            unsafe 
            {       
                int x = 0;
                int y = 0;
                int z = 0;
                bar(&x, &y, &z);
                Console.WriteLine(x);
                Console.WriteLine(y);
                Console.WriteLine(z);
            }
        }

        unsafe static void bar(params int *[] pInts)
        {
            int i = 0;
            foreach (var pInt in pInts)
            {
                *pInt = i++;
            }
        }
    }
}
like image 23
Scott Wisniewski Avatar answered May 19 '23 19:05

Scott Wisniewski