C#引用数组没有不安全

时间:2015-10-07 15:08:13

标签: c# arrays pointers ref

我发现了类似的主题,但我无法解决我读过它们的问题。

我想在C#中做同样的事情就像C中的指针数组一样,但我不想在C#指针中使用,因为它需要使用" unsafe"。

如何构建一个" ref to int"当我更改该数组的任何元素时,我也会在它指向的变量的同时更改它所引用的内容(就像在C - 指针数组中一样)。

祝你好运, 克里斯

2 个答案:

答案 0 :(得分:3)

如果性能不是问题,那么一个常见的解决方法是使用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

答案 1 :(得分:0)

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

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, <- Original
1, 2, 3, 4, 744477516, 6, 7, 8, 9, 10, <- Modified in Main
1, 2, 102109069, 4, 744477516, 6, 7, 8, 9, 10, <- Modified in ModArray
1, 2, 102109069, 4, 744477516, 6, 7, 8, 1776657318, 10, <- array, after modifying array2
1, 2, 102109069, 4, 744477516, 6, 7, 8, 1776657318, 10, <- array2

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

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

另见:

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

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