从方法 C# 返回数组
Returning array from methods C#
我一直在想,为什么我的方法不是修改数组,当我将它用作参数并使它等于另一个具有不同值的数组时,在方法内部?
我只是在更改参考地址吗?
static void Main()
{
string[] array = { "yes", "no", "maybe" };
TestO(array); // Still "yes", "no", "maybe"
}
static void TestO(string[] array)
{
string[] secondArray = new string[array.Length];
secondArray[0] = "1";
secondArray[1] = "2";
secondArray[2] = "3";
array = secondArray;
}
我的猜测:我没有修改 Main() 中的数组,因为在 Test0()
方法中执行 array = secondArray;
时,
我只是把array
的引用地址改成了secondArray
.
如果我的猜测不对,我的问题是,为什么它没有被修改?
(我知道我可以将 Test0()
修改为 string[]
return 方法和 return 修改后的 secondArray
并将其传递给array
在 Main()
)
另外一个问题是:
如果我使用 string[]
return 方法,并声明如下:
static void Main()
{
string[] array = { "yes", "no", "maybe" };
array = TestO(array);
}
static string[] TestO(string[] methodArray)
{
string[] secondArray = new string[methodArray.Length];
secondArray[0] = "1";
secondArray[1] = "2";
secondArray[2] = "3";
return secondArray;
}
array = TestO(array);
我只是将 secondArray[]
的参考地址传递给 array[]
还是我只传递它的值? (应该是参考地址,但我想确定是否弄错了)
您不需要 return 任何东西,只需使用 ref
static void Test( ref string[] array)
{
string[] secondArray = new string[array.Length];
secondArray[0] = "1";
secondArray[1] = "2";
secondArray[2] = "3";
array = secondArray;
}
当您将数组传递给方法时
static void Test0(string[] array)
{
您正在向该数组传递一个 引用。该引用实际上是 immutable(您得到的是引用的副本,而不是原始引用),因此您不能更改参数引用并期望它影响外部代码测试方法。
虽然您可以这样做以获得您想要的行为:
static void Test0(ref string[] array)
{
它不被认为是好的 C# 风格。字符串本身是不可变的; “正确”的风格是 return 他们从方法。字符串数组也是如此。
使用此技术唯一可以节省的是额外的引用和 return
语句,因为无论如何您仍在创建新字符串和新数组。
I just changed the reference address of array to secondArray. If my guess is not right, my question is, why exactly is it not getting modified?
我认为你倾向于理解内存中有两个对一个数据的引用(没有两个数据);您有一个指向数据的变量 array
。您调用一个方法,另一个方法,复制引用建立到相同的数据。您创建了一个新对象,然后将复制的引用指向新对象,将原始引用指向原始数据,然后您丢弃了复制引用和新数据。您又回到了完全相同的情况开始于。
逐行图示(我将您的方法参数重命名为 arrayX
,所以区别很明显):
如果你用ref
装饰参数并用ref
调用它没有副本,所以被调用的方法可以修改原始引用并将它指向其他地方:
请注意,在这些情况的任一中,完全可以修改数组的内容。正在做:
arrayX[0] = "New data";
.. 将在 或者 情况下生效并且打印 array[0]
将显示“新数据”。修改箭头末端的数据时,起点是原始参考还是副本并不重要。这纯粹关于方法是否有权将传递给它的原始引用指向不同的对象
通常我们不这样做。我们采用您的第二个代码块的样式 - return 数据。将其视为粗鲁可能会有所帮助 - 想象一下您的朋友说他会在您度假时照看您的植物;你把钥匙给了你的朋友。他把你的植物换成他更喜欢的另一种植物;你很不高兴,因为你有那株植物十年了..
很少有理由使用 ref
或相关的“覆盖您的引用的权力”- out
。不要将它用于“我想从我的方法中 return 多个东西”——在面向对象的世界中,我们总是可以 return 一个东西代表两个数据项。我们不需要“return两件事”;我们可以 return 一件东西里面有两件东西...
//don't:
void GetPerson(ref string name, ref int age)
//consider a class:
Person GetPerson()
return new Person(){ Name = ..., Age = ...}
//or a Tuple
(string Name, int Age) GetPerson
让调用方法选择是否应该覆盖它自己的变量,而不是让一些“第三方”把地毯从它脚下拉下来
我一直在想,为什么我的方法不是修改数组,当我将它用作参数并使它等于另一个具有不同值的数组时,在方法内部? 我只是在更改参考地址吗?
static void Main()
{
string[] array = { "yes", "no", "maybe" };
TestO(array); // Still "yes", "no", "maybe"
}
static void TestO(string[] array)
{
string[] secondArray = new string[array.Length];
secondArray[0] = "1";
secondArray[1] = "2";
secondArray[2] = "3";
array = secondArray;
}
我的猜测:我没有修改 Main() 中的数组,因为在 Test0()
方法中执行 array = secondArray;
时,
我只是把array
的引用地址改成了secondArray
.
如果我的猜测不对,我的问题是,为什么它没有被修改?
(我知道我可以将 Test0()
修改为 string[]
return 方法和 return 修改后的 secondArray
并将其传递给array
在 Main()
)
另外一个问题是:
如果我使用 string[]
return 方法,并声明如下:
static void Main()
{
string[] array = { "yes", "no", "maybe" };
array = TestO(array);
}
static string[] TestO(string[] methodArray)
{
string[] secondArray = new string[methodArray.Length];
secondArray[0] = "1";
secondArray[1] = "2";
secondArray[2] = "3";
return secondArray;
}
array = TestO(array);
我只是将 secondArray[]
的参考地址传递给 array[]
还是我只传递它的值? (应该是参考地址,但我想确定是否弄错了)
您不需要 return 任何东西,只需使用 ref
static void Test( ref string[] array)
{
string[] secondArray = new string[array.Length];
secondArray[0] = "1";
secondArray[1] = "2";
secondArray[2] = "3";
array = secondArray;
}
当您将数组传递给方法时
static void Test0(string[] array)
{
您正在向该数组传递一个 引用。该引用实际上是 immutable(您得到的是引用的副本,而不是原始引用),因此您不能更改参数引用并期望它影响外部代码测试方法。
虽然您可以这样做以获得您想要的行为:
static void Test0(ref string[] array)
{
它不被认为是好的 C# 风格。字符串本身是不可变的; “正确”的风格是 return 他们从方法。字符串数组也是如此。
使用此技术唯一可以节省的是额外的引用和 return
语句,因为无论如何您仍在创建新字符串和新数组。
I just changed the reference address of array to secondArray. If my guess is not right, my question is, why exactly is it not getting modified?
我认为你倾向于理解内存中有两个对一个数据的引用(没有两个数据);您有一个指向数据的变量 array
。您调用一个方法,另一个方法,复制引用建立到相同的数据。您创建了一个新对象,然后将复制的引用指向新对象,将原始引用指向原始数据,然后您丢弃了复制引用和新数据。您又回到了完全相同的情况开始于。
逐行图示(我将您的方法参数重命名为 arrayX
,所以区别很明显):
如果你用ref
装饰参数并用ref
调用它没有副本,所以被调用的方法可以修改原始引用并将它指向其他地方:
请注意,在这些情况的任一中,完全可以修改数组的内容。正在做:
arrayX[0] = "New data";
.. 将在 或者 情况下生效并且打印 array[0]
将显示“新数据”。修改箭头末端的数据时,起点是原始参考还是副本并不重要。这纯粹关于方法是否有权将传递给它的原始引用指向不同的对象
通常我们不这样做。我们采用您的第二个代码块的样式 - return 数据。将其视为粗鲁可能会有所帮助 - 想象一下您的朋友说他会在您度假时照看您的植物;你把钥匙给了你的朋友。他把你的植物换成他更喜欢的另一种植物;你很不高兴,因为你有那株植物十年了..
很少有理由使用 ref
或相关的“覆盖您的引用的权力”- out
。不要将它用于“我想从我的方法中 return 多个东西”——在面向对象的世界中,我们总是可以 return 一个东西代表两个数据项。我们不需要“return两件事”;我们可以 return 一件东西里面有两件东西...
//don't:
void GetPerson(ref string name, ref int age)
//consider a class:
Person GetPerson()
return new Person(){ Name = ..., Age = ...}
//or a Tuple
(string Name, int Age) GetPerson
让调用方法选择是否应该覆盖它自己的变量,而不是让一些“第三方”把地毯从它脚下拉下来