Not a variable

  • Thread starter Thread starter julio
  • Start date Start date
J

julio

What's wrong with this?

var d = new Dictionary<int, Pair>();
d[100] = new Pair(10, 20);
d[100].first = 11;

I get (abbreviated) "cannot modify return value of ...Dictionary<int,
Pair>.this[int] b/c not a variable".
Here I have

public struct Pair {
public int first;
public int second;
public Pair(int f, int s) { first = f ; second = s;}
}
 
julio said:
What's wrong with this?

var d = new Dictionary<int, Pair>();
d[100] = new Pair(10, 20);
d[100].first = 11;

I get (abbreviated) "cannot modify return value of ...Dictionary<int,
Pair>.this[int] b/c not a variable".
Here I have

public struct Pair {
public int first;
public int second;
public Pair(int f, int s) { first = f ; second = s;}
}

Use a class Pair if you want that code to work. A struct is a value type so
d[100].first = 11
is not going to work, you would need to do e.g
Pair p = d[100];
p.first = 11;
for a struct.
 
What's wrong with this?

var d = new Dictionary<int, Pair>();
d[100] = new Pair(10, 20);
d[100].first = 11;

I get (abbreviated) "cannot modify return value of ...Dictionary<int,
Pair>.this[int] b/c not a variable".
Here I have

public struct Pair {
public int first;
public int second;
public Pair(int f, int s) { first = f ; second = s;}
}

How about

d.Add(100, new Pair(10, 20));

instead of

d[100] = new Pair(10, 20);

Just guessing, since you didn't specify WHERE (i.e., on which line) you get
the error.
 
Nonsense,

Pair p = d[100];
p.first = 11;

obviously doesn't do anything to d. "A class" just like that won't work
either, b/c a dictionary key needs to implement GetHashCode and equals, which
will complicate everything further.


Martin Honnen said:
julio said:
What's wrong with this?

var d = new Dictionary<int, Pair>();
d[100] = new Pair(10, 20);
d[100].first = 11;

I get (abbreviated) "cannot modify return value of ...Dictionary<int,
Pair>.this[int] b/c not a variable".
Here I have

public struct Pair {
public int first;
public int second;
public Pair(int f, int s) { first = f ; second = s;}
}

Use a class Pair if you want that code to work. A struct is a value type so
d[100].first = 11
is not going to work, you would need to do e.g
Pair p = d[100];
p.first = 11;
for a struct.
 
Julio said:
"A class" just like that won't work
either, b/c a dictionary key needs to implement GetHashCode and equals, which
will complicate everything further.

But Pair is not the type of the key in your dictionary but the type of
the value so using class Pair instead of struct Pair should work.
 
Nonsense,

Pair p = d[100];
p.first = 11;

obviously doesn't do anything to d. "A class" just like that won't work
either, b/c a dictionary key needs to implement GetHashCode and equals,
which
will complicate everything further.

Your dictionary's key is an int, not a Pair, so Pair does not need to
implement GetHashCode().
 
Nonsense,

Pair p = d[100];
   p.first = 11;

obviously doesn't do anything to d. "A class" just like that won't work
either, b/c a dictionary key needs to implement GetHashCode and equals, which
will complicate everything further.

All structs implement Equals() and GetHashCode() structurally. It's
not a very reasonable or fast implementation, but it works.
 
julio said:
What's wrong with this?
var d = new Dictionary<int, Pair>();
d[100] = new Pair(10, 20);
d[100].first = 11;
I get (abbreviated) "cannot modify return value of ...Dictionary<int,
Pair>.this[int] b/c not a variable".  
Here I have
public struct Pair {
public int first;
public int second;
public Pair(int f, int s) { first = f ; second = s;}
}

Use a class Pair if you want that code to work. A struct is a value type so
   d[100].first = 11
is not going to work, you would need to do e.g
   Pair p = d[100];
   p.first = 11;
for a struct.

It looks like he's trying to change the value within the dictionary.
If so, your code snippet won't help him as it creates the copy and
modifies that copy. The last obvious step after that would be:

d[100] = p;
 
It looks like he's trying to change the value within the dictionary.
If so, your code snippet won't help him as it creates the copy and
modifies that copy. The last obvious step after that would be:
d[100] = p;

Oh, is that what's happening, a copy is being created? I see.
 
julio said:
What's wrong with this?

var d = new Dictionary<int, Pair>();
d[100] = new Pair(10, 20);
d[100].first = 11;

I get (abbreviated) "cannot modify return value of ...Dictionary<int,
Pair>.this[int] b/c not a variable".

You wouldn't try to do this:

int a = 1, b = 2;
(a + b) = 5;

Although your example looks a little different, it is in fact the same.
d[100] is a computation which stores its result in a temporary, and changing
the temporary copy has no effect.

C# used to allow that code, which silently did nothing. Microsoft decided
(correctly) that a compile error was better than silent unexpected behavior.

Changing Pair to a struct as others suggested will solve your problem. This
is because the computation will store a temporary copy of the reference...
the object referred to is neither temporary nor a copy, and changes you make
to its members will be persistent.
 
Back
Top