Not a variable

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;}
}
 
M

Martin Honnen

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.
 
J

Jeff Johnson

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.
 
J

Julio

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.
 
M

Martin Honnen

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.
 
J

Jeff Johnson

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().
 
P

Pavel Minaev

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.
 
P

Pavel Minaev

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;
 
J

Jeff Johnson

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.
 
B

Ben Voigt [C++ MVP]

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top