7

我希望能够在不直接引用它们的情况下为列表对象分配值:

伪示例:

List<int> intList = new List<int> { 0 };
???? intPointer = ref intlist[0];

*intPointer = 1;  // I know * isn't possible here, but it is what I'd like to do

Console.WriteLine(intList[0]);

它会输出1.

我认为这是不可能的,但我只是想确保我没有遗漏任何东西。

另外,我不是在寻找使用的示例unsafe,我很好奇这在托管代码中是否可行。

4

3 回答 3

12

C# 没有“ref locals”的概念(虽然 CLR 有)。因此,您需要将值包装在可以变异的引用类型中。例如,

public class Ref<T> where T : struct
{
    public T Value {get; set;}
}

List<Ref<int>> intRefList = new List<Ref<int>>();
var myIntRef = new Ref<int> { Value = 1 };
intRefList.Add(myIntRef);

Console.WriteLine(myIntRef.Value);//1

Console.WriteLine(intRefList[0].Value);//1

myIntRef.Value = 2;

Console.WriteLine(intRefList[0].Value);//2

编辑:C# 7.0 添加了ref locals但它们仍然不能以这种方式使用,因为您不能将 ref locals 放入数组或列表中。

于 2012-11-14T00:54:04.093 回答
4

不,这在 C# 中是不可能的。

C# 不支持对局部变量的引用,其中包括对本地容器元素的引用。

在 C# 中获得真正的引用(即,不是引用类型的实例,而是对另一个变量的实际引用)的唯一方法是通过reforout参数关键字。这些关键字不能与任何类型的索引值或属性一起使用,其中包括List<>. 您也无法直接控制这些引用:编译器在幕后为您执行取消引用。

有趣的是,CLR确实支持这种引用。如果您将 CIL 反编译成 C#,您有时会看到类似的类型int&是对int. C# 故意不允许您在代码中直接使用这些类型。

于 2012-11-14T00:55:05.593 回答
0

使用诸如 int 之类的值类型时,您要问的问题是不可能的。您将需要额外的间接级别;例如,您可以包装您的整数。

有关该示例,请参见传递给迭代器的值类型的可变包装器。

于 2012-11-14T00:53:16.727 回答