我想做这样的事情:
double a, b, c, d, e;
ParseAndWrite("{1, 2, 3}", ref a, ref b, ref c);
ParseAndWrite("{4, 5}", ref d, ref e);
-> a = 1, b = 2, c = 3, d = 4, e = 5
但是,我不能写这样的函数:
private void ParseAndWrite(string leInput, params ref double[] targets)
{
(...)
}
这行不通,出于某种原因不能同时使用 ref 和 params。为什么会这样?
编辑:好的,这里有一些关于我为什么需要这个的更多信息:通过一个接口(interface),我得到了很多包含值的字符串,语法如下:
inputConfig : " step, stepHeight, rStep, rStepHeight, (nIterations, split, smooth) "
outputConfig : " dataSelection, (corrected, units, outlierCount, restoreOriginalRange) "
(括号中的名称是可选的)。这些值需要被解析并存储在所有特定变量中。也就是说——它们根本不是数组。它们更像是命令行参数,但大约有 20 个。我当然可以按顺序执行所有这些操作,但这会产生数百行包含冗余模式且难以维护的代码。
最佳答案
for some reason one can not use ref and params at the same time. Why so?
考虑相机的这三个理想特性:
轻量级
高品质镜头
便宜
在任何相机中您最多只能拥有两个。你永远不会得到所有三个。您可以获得廉价的重型大镜头相机,或昂贵的轻型大镜头相机,或便宜的轻型快照相机,但没有带大镜头的廉价轻型相机。
现在回到你的问题。考虑运行时的这三个理想特征:
ref-to-variable 类型的参数数组是合法的
类型系统是安全的
具有引用的局部变量仍然可以快速分配和释放
你可以拥有任何两个,但你不能拥有所有三个。你想要哪两个?
您可以拥有引用参数数组和安全类型系统,代价是将引用的局部变量分配到垃圾收集堆上。据我所知,没有人这样做,但这当然是可能的。
你可以有 ref param 数组,分配在临时池上的所有局部变量,以及一个当你使用错误时崩溃的类型系统。这是“C/C++”方法;可以获取引用并将其存储在生命周期比被引用事物的生命周期更长的位置。如果这样做,您可能会犯下难以检测的简单错误,从而导致 C++ 程序崩溃并以最可怕的方式死亡。欢迎来到绝望的深渊。
或者我们可以使 ref param 数组非法,在临时池上分配所有局部变量,并拥有一个可验证内存安全的类型系统。这是我们在构建 C# 和 CLR 时做出的选择;欢迎来到质量的坑。
现在,我上面所说的实际上都是一个弥天大谎。这是一个谎言,因为运行时和 C# 语言实际上确实支持类似于(但不完全相同)refs 参数数组的功能。这是一个令人愉快的谎言,相信我,你想生活在你相信谎言的世界里,所以我建议你服用蓝色药丸并继续这样做。
如果您想采取红色药丸并找出兔子洞有多深,您可以使用 C# 的未记录的 __arglist
功能构建一个C 风格的可变参数方法,然后制作 TypedReference
对象,引用任意字段的引用或结构类型的局部变量,然后将任意多个对象传递给可变参数方法。使用 TypedReference
的工厂方法或 C# 的未记录的 __makeref
功能。
我们在过去十年中一直未对这些功能进行记录的原因是,根据设计,它们仅用于极其罕见的情况,在这些情况下,您必须编写与用其他语言编写的可变参数方法干净地互操作的 C# 代码。
正确使用 TypedReference
对象并不适合胆小的人,我再次强烈建议不要这样做。在多年编写 C# 的过程中,我从未在生产代码中这样做过。如果您想传递对任意多个变量的引用,传递一个数组。根据定义,数组是变量的集合。这比传递一堆表示实例或局部变量的托管地址的对象要安全得多。
关于c# - 为什么我不能将不同数量的引用传递给一个函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8416740/