在C++中,我可以这样做:
int i[10] = new int[10];
int *p = &i[5];
Run Code Online (Sandbox Code Playgroud)
然后,我总是可以知道p指向int数组i的第5个元素,不管我的内容是什么.
有没有办法在C#中做类似的事情?
我意识到这可能是C#"保护"我们自己的方式之一,所以我不是在寻找一个完全相同的,而是一个类似的概念......也就是说,能够参考某些内容其他变量,而不是变量本身的实例.
这是我正在考虑的用例.我有一个字符串数组.我想有另一个数组元素的引用数组.像这样的东西(显然不是有效的代码):
string[] s = new string[] { "one", "two", "three", "four", "five", "six" };
stringref[] sr = new stringref[] { &s[0], &s[1], &s[2], &s[3], &s[4], &s[5] };
Console.WriteLine(sr[1]); // == "two"
s[1] = "two point zero";
Console.WriteLine(sr[1]); // == "two point zero"
Run Code Online (Sandbox Code Playgroud)
当然,ref参数执行此操作,out参数允许您写入特定变量.但是非参数怎么样?你可以存储参考吗?你能保留一系列的参考文献或字典吗?
似乎是否存在使用参数执行此操作的能力,应该有一种方法可以在没有它们的情况下执行此操作.
Meh*_*ari 21
不.将unsafe代码放在一边,这允许保存指向内存位置的指针,没有办法在C#中存储对变量的引用.
ref和out参数提供了获取引用的唯一方法,但您无法将它们保存在任何地方.
您可以通过在a中包装字段class并使用其引用来解决此限制.这是编译器在闭包中捕获变量的方法:
例如,当你写:
int integer = 0;
Action<int> method = i => Console.WriteLine(i + integer);
integer = 42;
method(100); // prints 142, not 100
Run Code Online (Sandbox Code Playgroud)
在第二行中,编译器必须取出匿名方法并将其作为单独的方法存储在类中.显然,该方法无法访问integer变量.它以某种方式需要将integer变量的"引用"传递给该匿名方法.由于它不可能,它将生成一个class带有字段来保存整数并使用该类的实例来存储变量.基本上,局部变量被提升为类中的字段并存储在堆中.
只读数组引用:
class ArrayRef<T>
{
private T[] array;
private int index;
public ArrayRef(T[] array, int index)
{
this.array = array;
this.index = index;
}
public static implicit operator T(ArrayRef self)
{
return self.array[self.index];
}
}
var s = new string[] { "one", "two", "three", "four", "five", "six" };
var sr = new ArrayRef<string>[] { new ArrayRef<string>(s, 0), new ArrayRef<string>(s, 1), new ArrayRef<string>(s, 2), new ArrayRef<string>(s, 3), new ArrayRef<string>(s, 4), new ArrayRef<string>(s, 5) };
Console.WriteLine(sr[1]); // == "two"
s[1] = "two point zero";
Console.WriteLine(sr[1]); // == "two point zero"
Run Code Online (Sandbox Code Playgroud)
从 C#7 开始,可以定义数组中的元素或对象中的字段的局部引用:
string[] s = new string[] { "one", "two", "three", "four", "five", "six" };
ref string sr1 = ref s[1]; // a ref local to an element in an array
Console.WriteLine(sr1); // == "two"
sr1 = "two point zero";
Console.WriteLine(s[1]); // == "two point zero"
Run Code Online (Sandbox Code Playgroud)