【问题标题】:C# array of references without unsafe没有不安全的 C# 引用数组
【发布时间】:2016-01-04 21:39:55
【问题描述】:

我找到了类似的主题,但我无法解决我阅读它们时遇到的问题。

我想在 C# 中做与 C 中相同的事情是指针数组,但我不想在 C# 中使用指针,因为它需要使用“不安全”。

如何构建一个“ref to int”数组,当我更改该数组的任何元素时,我还将更改它所引用的内容,同时它指向的变量(就像在 C - array of指针)。

最好的问候, 克里斯

【问题讨论】:

  • 您可能必须构建自己的类来处理这个问题。但是,为什么普通数组对你无效?
  • 你不能,基本上。如果数组中填充了对局部变量的引用,然后该局部变量从堆栈中弹出,您会期望发生什么?您可以创建自己的“包装器”类,可能是通用的,并在调用代码中维护Wrapper<int> 引用和在操作代码中维护Wrapper<int>[]...
  • 您可以使用 out 参数,该参数基本上可以作为参考工作。

标签: c# arrays pointers ref


【解决方案1】:

如果性能不是问题,一种常见的解决方法是使用 lambda 来捕获对值类型变量的访问:

示例:

class GetSetPair<T> 
{
    public Func<T> Get {get;set;}
    public Action<T> Set {get;set;}
}


var referencesToInt = new List<GetSetPair<int>>();

int value = 42;
referencesToInt.Add(new GetSetPair<int>{Get=()=>value, Set = v => value = v});
referencesToInt[0].Set(33);
Console.WriteLine(value); // 33
value = 22;
Console.WriteLine(referencesToInt[0].Get()); //22

【讨论】:

  • 您可能希望将 Func&lt;int&gt; 更改为 Func&lt;T&gt; 等。
  • @Bauss 谢谢。清理/验证它可以编译。
【解决方案2】:

数组是引用类型,因此您可以传递对该数组的引用。例如,给定以下程序:

public class Program
{
    public static Random rnd = new Random();
    public static int[] array2;

    public static void Main()
    {
        int[] array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        PrintArray(array);
        array[4] = rnd.Next();
        PrintArray(array);
        ModArray(array, 2);
        PrintArray(array);

        array2 = array;  //This makes array2 reference array1

        ModArray(array2, 8);  //Operate on the array2 reference
        PrintArray(array);    //Changes are reflected in array
        PrintArray(array2);   //And in array2

        Console.ReadKey(true);
    }

    public static void PrintArray(int[] array)
    {
        foreach (var e in array)
            Console.Write(e + ", ");
        Console.WriteLine();
    }

    public static void ModArray(int[] array, int i)
    {
        array[i] = rnd.Next();
    }
}

将给出以下输出:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10,

所以从某种意义上说,您可以传递对数组的引用,修改该引用,并将其反映在其所有副本中。

这里需要注意的是,任何“拥有”对原始数组的引用的人都不能重新分配该数组(或调整它的大小)。它可以修改数组的元素,但它不能使原始数组指向一个新实例(这是调整大小时发生的情况)。此外,正如 Jon Skeet 在他的评论中提到的那样,危险在于,如果您使用 Main 以外的其他方法执行此操作,如果 array 超出范围,array2 会发生什么情况?

另见:

Is int[] a reference type or a value type?

Are arrays or lists passed by default by reference in c#?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    相关资源
    最近更新 更多