在C#中,是否有一种使用变量参数来传递引用的方法?

4

我希望有一个函数,可以修改一些变量列表的参数,但它们都是值类型(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关键字可能没有太多用处。

在这种情况下,重载/引用方法在什么时候会失效? - Marc Gravell
我同意Marc的观点。我不禁感到你的需求指向了一个设计问题。 - OJ.
3个回答

8

好的,您可以声明一些重载,例如:

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

否则,您将不得不从数组中读取(因为params确实意味着“隐式数组”):

等等

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

(当然,如果它只接受int,最好在整个过程中使用int[]

我对我的问题进行了更详细的阐述,解释了为什么这种方法在这种情况下并不太有用,无论如何还是谢谢。 - Edwin Jarvis

5

可以,但生成的代码是“不安全”的,这使其无法验证。

根据您的要求,这可能或可能不是一个问题。

无论如何,以下是代码:

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

很遗憾它们需要被改变;在类似的复杂程度上,还有可变参数(http://www.eggheadcafe.com/articles/20030114.asp),但是当然这不允许改变。 - Marc Gravell
当我在微软工作时(作为VB编译器团队的开发人员),我的办公室同事是一名测试人员(也在VB上工作)。一个有点成为笑话的领域是,在他参加的每次测试评审中(关于新语言特性),“如何与ArgIterator配合工作”这个问题总是被提出。 - Scott Wisniewski
@Scott,哦,是的,可怕的ArgIterator。QA喜欢那个类。 - JaredPar

2
不,没有一个简洁的语法可以实现这个。原因是内部运行时将该方法视为一个简单的方法,接受一个数组参数。编译器会负责创建一个数组并用指定的参数填充它。由于参数是值类型,它们将被复制到数组中,并且对它们的任何更改都会影响原始变量。
其他实现方式将违背params的存在目的,而params则提供了一种美观易读的语法来处理可变数量的参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接