在C#中有一种使用变量参数通过引用传递的方法?

在C#中有一种使用变量参数通过引用传递的方法?,c#,reference,params,C#,Reference,Params,我希望有一个函数可以修改一些参数的变量列表,但它们都是值类型(int,string)。有一种方法可以使params关键字与ref关键字或类似的东西一起工作吗 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; func

我希望有一个函数可以修改一些参数的变量列表,但它们都是值类型(int,string)。有一种方法可以使params关键字与ref关键字或类似的东西一起工作吗

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);
}
问题是,我试图让我的生活变得更轻松,制作一个修改对象字段的方法。我正在使用Cecil进行一些动态代码生成,我试图避免编写太多IL生成的代码


为了简化,我想通过引用传递字段列表,我需要更改为更改字段的函数,而不是通过生成相应的IL来更改字段。有些参数是可以为空的,这会使代码生成更加痛苦。在这种情况下,使用一些重载方法而不是参数将没有多大用处。

不,使用简洁的语法是不可能的。原因是,在内部,运行库将该方法视为采用数组参数的简单方法。编译器负责创建数组并用指定的参数填充数组。由于参数是值类型,它们将被复制到数组中,对它们的任何更改都不会影响原始变量。
实现它的其他方法将破坏
params
存在的目的,这是一种适用于可变数量参数的好语法。

好吧,您可以声明一些重载,即

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

否则,您必须从数组中读回(因为
params
实际上意味着“隐式数组”):

(当然,如果它只接受
int
s,最好始终使用
int[]

是。这是可能的

但是,生成的代码是“不安全的”,因此无法验证

这可能是问题,也可能不是问题,取决于您的要求

在任何情况下,代码如下:

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

我确实详细阐述了我的问题,解释了为什么这种方法在这种情况下没有太多用处,无论如何,谢谢。可惜它们需要变异;在类似的复杂程度上,还有varargs(),但这当然不允许变异。当我在Microsoft工作时(作为VB编译器团队的开发人员),我的办公室伙伴是一名测试人员(也是在VB上)。有一个领域一直是一个笑话,那就是在他每次去(关于新的语言特性)的测试回顾中,“它如何与ArgIterator一起工作”这个问题总是出现。@Scott,哦,是的,可怕的ArgIterator。QA喜欢那个类。在那个场景中,ref/重载方法在什么时候崩溃了?我同意Marc的观点。我忍不住觉得您的需求指向了一个设计问题。
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++;
            }
        }
    }
}