Why can't I pass indexer as a ref parameter?

849 Views Asked by At

I understand the rule. But who knows why this is?

If my code is:

List<T> x = new List<T>;
x.Add(new T());
x.Add(new T());
x.Add(new T());

int y = 2;

//And I call a method 
M1(ref x[y]);

ref x[y] is just a pointer to my instance of T of interest isn't it?

Why can't I write the line of code call it M1() in the very simple fashion.

.

I know the workaround:

T cX = x[y];
M1(ref cX);

I'm hoping to hear why the architects of c# require this extra step to pass a pointer? Or is it a compiler limitation?

2

There are 2 best solutions below

1
On BEST ANSWER

An indexer value is not classified as a variable; therefore, you cannot pass an indexer value as a ref or out parameter.

Refer msdn

7
On

ref x[y] is just a pointer to my instance of T of interest isn't it?

Well, if T is a reference type, then yes. If T is a value type then no, but that doesn't matter, let's assume for the moment it is. Since the method is ref T it needs to accept a reference to a variable which is pointer to an instance of T. You just have a pointer, not a storage location for a pointer. (Note that I'm staying within your analogy. Technically you don't have a "pointer", you have a reference to the object, but the analogy is good enough for the purposes of this question.)

The getter of the indexer of a list doesn't resolve to a storage location for a given value, it resolves to just a value. Also note that when you write:

T cX = x[y];
M1(ref cX);

That you're not reflecting any mutations of cX back to the list. You'd need to write:

T cX = x[y];
M1(ref cX);
x[y] = cX;

for it to actually be equivalent to ensure that any mutations to the variable cX in M1 are reflected in the list.