繁体   English   中英

C#使用params关键字的结果不一致

[英]C# Inconsistent results using params keyword

给出以下方法:

static void ChangeArray(params string[] array) {

    for (int i = 0; i < array.Length; i++) 
        array[i] = array[i] + "s";
}

如果我调用它传递一个字符串数组,这是有效的:

string[] array = {"Michael", "Jordan"} // will become {"Michaels", "Jordans"}
ChangeArray(array);

但如果我使用字符串参数调用它将无法工作:

string Michael = "Michael";
string Jordan = "Jordan";
ChangeArray(Michael, Jordan); // This will NOT change the values of the variables

我知道编译器会将Michael和Jordan包装在一个数组上,所以两种情况下结果不一样吗?

你的第二个例子基本上是:

string Michael = "Michael";
string Jordan = "Jordan";
{
    var tmp = new string[] {Michael, Jordan};
    ChangeArray(tmp);
}

所以; 实际上, tmp 的值已经改变了......但之后丢弃了tmp ,所以你什么都看不到。 params 并不模拟ref -它不会做的位置明智更新回原始变量。 或者在代码中,它不是以下内容:

string Michael = "Michael";
string Jordan = "Jordan";
{
    var tmp = new string[] {Michael, Jordan};
    ChangeArray(tmp);
    Michael = tmp[0];
    Jordan = tmp[1];
}

如果你需要它那样做,然后像这些代码是-或改用一个重载需要ref的参数。

原因是string是一个不可变类型 - 您传入包含在数组中的string实例。 该数组现在包含两个新字符串(具有与原始字符串相同但不同实例的值)。 更改阵列时,这些副本将被丢弃,阵列插槽将保留一个新字符串。 当函数返回时,临时数组将被丢弃。 因此,您的原始输入字符串永远不会被修改(它们无论如何都不可能,因为string是 - 再次 - 不可变的)。

编辑我在评论中李的论点后对这个答案进行了编辑(我将保留答案,只是为了完成以下讨论)。 不可变部分确实与问题无关。 主要的根本问题是对被丢弃的临时数组进行了更改。

这很奇怪(我不知道这个),但是如规定的那样

参数数组允许在方法调用中以两种方式之一指定参数:

为参数数组提供的参数可以是可隐式转换(第6.1节)到参数数组类型的类型的单个表达式。 在这种情况下,参数数组的作用就像一个值参数。

或者,调用可以为参数数组指定零个或多个参数,其中每个参数都是可隐式转换(第6.1节)到参数数组的元素类型的类型的表达式。 在这种情况下,调用创建参数数组类型的实例,其长度对应于参数的数量,使用给定的参数值初始化数组实例的元素,并使用新创建的数组实例作为实际参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM