繁体   English   中英

在静态类方法中通过引用传递参数

[英]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.

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