afuzzyllama
afuzzyllama

Reputation: 6548

Possible to store references to objects in list?

I would like to be able to assign values to list objects without directly referencing them:

Pseudo example:

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]);

and it would output 1.

I'm thinking that this isn't possible, but I just wanted to make sure I wasn't missing anything.

Also, I'm not looking for an example that uses unsafe, I'm curious if this is possible in managed code.

Upvotes: 9

Views: 24184

Answers (3)

Wesley Wiser
Wesley Wiser

Reputation: 9851

C# doesn't have a concept of "ref locals" (the CLR does though). So you'll need to wrap the values in a reference type that you can mutate. For example,

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

Edit: C# 7.0 added ref locals but they still can't be used in this way because you can't put ref locals into an array or list.

Upvotes: 14

Michael Edenfield
Michael Edenfield

Reputation: 28338

No, this is not possible in C#.

C# does not support references to local variables, which includes references to elements of local containers.

The only way to obtain a true reference in C# (that is, not an instance of a reference type, but an actual reference to another variable) is via the ref or out parameter keywords. Those keywords cannot be used with any sort of indexed value or property, which includes elements in a List<>. You also have no direct control over these references: the compiler performs the dereferencing for you, behind the scenes.

Interestingly, the CLR does support this kind of reference; if you decompile CIL into C# you will sometimes see types like int& that are references to int. C# purposely does not allow you to use these types directly in your code.

Upvotes: 4

Joseph Tanenbaum
Joseph Tanenbaum

Reputation: 2241

What you're asking is not possible when using a value type such as int. You'll need an additional level of indirection; You could wrap your integer for example.

See Mutable wrapper of value types to pass into iterators for an example of that.

Upvotes: 0

Related Questions