[英]Passing arguments by reference in static class methods
我收到错误消息“属性或索引器可能无法作为输出或引用参数传递”我的任务是将 buble 排序实现为静态类,如果我将其设为非静态,则它工作得很好。
public static class BubleSort
{
public static void Sort(List<int> arr)
{
for (int i = 0; i < arr.Count-1; i++)
{
var flag = true;
for (int j = 0; j < arr.Count-i-1; j++)
{
if (arr[j] > arr[j + 1])
{
Swap(ref arr[j],ref arr[j + 1]);
flag = false;
}
}
if (flag)
break;
}
}
private static void Swap(ref int v1,ref int v2)
{
int temp = v1;
v1 = v2;
v2 = temp;
}
}
你不能完全按照编译器所说的原因做你想做的事情......但是你可以只使用列表的引用
private static void Swap(IList<int> list, int i)
{
int temp = list[i];
list[i] = list[i+1];
list[i+1] = temp;
}
或使用元组解构的 1 衬里
if (arr[j] > arr[j + 1])
{
(arr[j], arr[j + 1]) = (arr[j + 1], arr[j]);
flag = false;
}
Indexer access returns temporary value. 'ref' argument must be an assignable variable, field or an array element
您不能从列表发送引用,因为对特定索引元素的访问是通过索引器完成的。 查看更多关于索引器
相反,您可以使用 ref 从数组int[]
发送引用,因为它不使用索引器,而是直接引用。
如果你仍然想使用列表,你可以使用 C# 特性来交换:
(arr[j],arr[j + 1]) = (arr[j + 1], arr[j]);
而不是Swap
方法
您的代码将成为
public static class BubleSort
{
public static void Sort(List<int> arr)
{
for (int i = 0; i < arr.Count-1; i++)
{
var flag = true;
for (int j = 0; j < arr.Count-i-1; j++)
{
if (arr[j] > arr[j + 1])
{
(arr[j],arr[j + 1]) = (arr[j + 1], arr[j]);
flag = false;
}
}
if (flag)
break;
}
}
}
语言中有一个返回引用的功能。 但这仅适用于数组,而不是列表,因为列表可以重新分配。 因此,如果您将arr
更改为数组,我希望您的示例代码能够正常工作。 例如,请参阅此最小示例:
public void SwapTest()
{
var arr = new [] {1, 2};
Swap( ref arr[0], ref arr[1]);
}
public static void Swap(ref int a, ref int b)
{
var tmp = a;
a = b;
b = tmp;
}
但是,对于大多数实际应用,我建议使用@TheGeneral 发布的解决方案之一。 ref 返回有点不寻常,可能不是所有程序员都熟悉。
在这种情况下, arr[j] 被视为一个属性,因为它需要读取 List 中的一个字段。 属性不是变量。 它们是方法,不能传递给 ref 参数。
如果你想这样做,你需要将数组属性传递给一个临时变量。
例子:
if (arr[j] > arr[j + 1]){
int tempJ = arr[j];
int tempJ2 = arr[j + 1];
Swap(ref tempJ, ref tempJ2);
arr[j] = tempJ;
arr[j + 1] = tempJ2;
flag = false;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.