4

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.

2
  • At what point does the ref/overload approach break down in that scenario? Commented Jan 12, 2009 at 12:08
  • I agree with Marc. I can't help but feel that your requirements point to a design issue. Commented Jan 12, 2009 at 12:18

3 Answers 3

8

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)

Sign up to request clarification or add additional context in comments.

1 Comment

I did elaborate a little more on my problem explaining why this approach isn't too much useful in this case, thanks anyway.
5

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++;
            }
        }
    }
}

3 Comments

It is a shame they need to be mutated; at a similar level of complexity, there is also varargs (eggheadcafe.com/articles/20030114.asp), but of course this doesn't allow mutation.
When I worked at Microsoft (as a dev on the VB compiler team), my office mate was a tester (also on VB). One area that was kind of a running joke was that in every test review he went to (about new language features), the question of "how does it work with ArgIterator" always came up.
@Scott, oh yes, the dreaded ArgIterator. QA loves that class.
2

No, it's not possible with a neat syntax. The reason is, internally, the runtime treats the method as a simple method taking an array argument. The compiler does the housekeeping of creating an array and filling it with the arguments specified. Since the arguments are value types, they will be copied to the array and any change to them will not affect the original variables. Other ways to accomplish it will defeat the purpose of existence of params which is a nice syntax for variable number of arguments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.