From: Andrew Falanga on
Hi,


As you know, I can't post the actual code. However, what's below is
basically a copy/paste, just cut down to illustrate without the
superfluous code.

The following code shows the problem:

namespace SomeSpace {
private struct Struct1 {
public object val;
public Struct1(object o) {
val = o;
}
}

public class MyClass {
Dictionary<string, Struct1> dict1;

public MyClass() {
dict1 = new Dictionary<string, Struct1>();
dict1.Add("key1", new Struct1(0)); // make the val an int32
dict1.Add("key2", new Struct1(0)); // ditto
}

public void F1() {
// need to fill the dictionary will some meaningful data from
// a config file

F2("myCfgFile.xml");

// now, do more meaningful stuff
}

public void F2(string path) {
// parsing routines using System.XML
// oh, something meaningful is found

dict1["key1"].val = Convert.ToInt32(xmlText); // here's my
error

}
}
}


At the point where it says, "here's my error," I'm getting an error
saying that I cannot modify the return value of Dictionary<string,
Struct1>[] because it is not a variable. What? It is to a variable,
it's an object variable in the structure.

Some digging on Google has brought me to a link that says this can't
be done because structures are allocated on the stack, instead of the
heap. The author of that response said it had to do with the
difference between value objects and reference objects. That's ok,
but I'm still at a loss for why this isn't working. Even the link
that he provided to the C# standard showed code example that looks
similar to what I've got, though not using dictionaries, but works.

Any help is greatly appreciated.

Andy
From: Jeff Johnson on
"Andrew Falanga" <af300wsm(a)gmail.com> wrote in message
news:a71b1bb4-7181-42da-8c6a-7779efdcad36(a)g5g2000pre.googlegroups.com...

> As you know, I can't post the actual code. However, what's below is
> basically a copy/paste, just cut down to illustrate without the
> superfluous code.

That's EXACTLY what we mean when we ask you to post real code. We mean only
RELEVANT code, so good job!

> The following code shows the problem:
>
> namespace SomeSpace {
> private struct Struct1 {
> public object val;
> public Struct1(object o) {
> val = o;
> }
> }
>
> public class MyClass {
> Dictionary<string, Struct1> dict1;
>
> public MyClass() {
> dict1 = new Dictionary<string, Struct1>();
> dict1.Add("key1", new Struct1(0)); // make the val an int32
> dict1.Add("key2", new Struct1(0)); // ditto
> }
>
> public void F1() {
> // need to fill the dictionary will some meaningful data from
> // a config file
>
> F2("myCfgFile.xml");
>
> // now, do more meaningful stuff
> }
>
> public void F2(string path) {
> // parsing routines using System.XML
> // oh, something meaningful is found
>
> dict1["key1"].val = Convert.ToInt32(xmlText); // here's my
> error
>
> }
> }
> }
>
>
> At the point where it says, "here's my error," I'm getting an error
> saying that I cannot modify the return value of Dictionary<string,
> Struct1>[] because it is not a variable. What? It is to a variable,
> it's an object variable in the structure.
>
> Some digging on Google has brought me to a link that says this can't
> be done because structures are allocated on the stack, instead of the
> heap. The author of that response said it had to do with the
> difference between value objects and reference objects. That's ok,
> but I'm still at a loss for why this isn't working. Even the link
> that he provided to the C# standard showed code example that looks
> similar to what I've got, though not using dictionaries, but works.

Because the value of your dictionary is a structure, when you access that
value you're actually getting a COPY of the structure, not the actual
structure object that you stored in the dictionary. This is because
structures are considered value types and value types are always passed by
value, not reference. The C# compiler understands this and knows that any
change you might make to a member of the returned structure would be made to
the COPY that you get and not to the original structure as is more than
likely your intention, and as such it disallows this action to save you from
yourself. In this particular case, I would think that the copy of the
structure would still point to the same object in val that the original
structure points to, and therefore changing val would indeed change the
original object. However, as I said, C# is simply designed not to let you do
this.

Someone please correct me if my interpretation is wrong.


From: Andrew Falanga on
On May 20, 12:53 pm, "Jeff Johnson" <i....(a)enough.spam> wrote:
> "Andrew Falanga" <af300...(a)gmail.com> wrote in message
>
> news:a71b1bb4-7181-42da-8c6a-7779efdcad36(a)g5g2000pre.googlegroups.com...
>
> > As you know, I can't post the actual code.  However, what's below is
> > basically a copy/paste, just cut down to illustrate without the
> > superfluous code.
>
> That's EXACTLY what we mean when we ask you to post real code. We mean only
> RELEVANT code, so good job!
>
>
>
> > The following code shows the problem:
>
> > namespace SomeSpace {
> >   private struct Struct1 {
> >      public object val;
> >      public Struct1(object o) {
> >         val = o;
> >      }
> >   }
>
> >   public class MyClass {
> >      Dictionary<string, Struct1> dict1;
>
> >      public MyClass() {
> >         dict1 = new Dictionary<string, Struct1>();
> >         dict1.Add("key1", new Struct1(0)); // make the val an int32
> >         dict1.Add("key2", new Struct1(0)); // ditto
> >      }
>
> >      public void F1() {
> >         // need to fill the dictionary will some meaningful data from
> >         // a config file
>
> >         F2("myCfgFile.xml");
>
> >         // now, do more meaningful stuff
> >      }
>
> >      public void F2(string path) {
> >         // parsing routines using System.XML
> >         // oh, something meaningful is found
>
> >         dict1["key1"].val = Convert.ToInt32(xmlText); // here's my
> > error
>
> >      }
> >   }
> > }
>
> > At the point where it says, "here's my error," I'm getting an error
> > saying that I cannot modify the return value of Dictionary<string,
> > Struct1>[] because it is not a variable.  What?  It is to a variable,
> > it's an object variable in the structure.
>
> > Some digging on Google has brought me to a link that says this can't
> > be done because structures are allocated on the stack, instead of the
> > heap.  The author of that response said it had to do with the
> > difference between value objects and reference objects.  That's ok,
> > but I'm still at a loss for why this isn't working.  Even the link
> > that he provided to the C# standard showed  code example that looks
> > similar to what I've got, though not using dictionaries, but works.
>
> Because the value of your dictionary is a structure, when you access that
> value you're actually getting a COPY of the structure, not the actual
> structure object that you stored in the dictionary. This is because
> structures are considered value types and value types are always passed by
> value, not reference. The C# compiler understands this and knows that any
> change you might make to a member of the returned structure would be made to
> the COPY that you get and not to the original structure as is more than
> likely your intention, and as such it disallows this action to save you from
> yourself. In this particular case, I would think that the copy of the
> structure would still point to the same object in val that the original
> structure points to, and therefore changing val would indeed change the
> original object. However, as I said, C# is simply designed not to let you do
> this.
>
> Someone please correct me if my interpretation is wrong.

I think I understand. So, more importantly, how can I alter the
values of the structure in that dictionary?

Andy
From: Jeff Johnson on
"Andrew Falanga" <af300wsm(a)gmail.com> wrote in message
news:64cb497b-99b8-4b3a-837e-1f0c7f1432a3(a)40g2000pry.googlegroups.com...

> I think I understand. So, more importantly, how can I alter the
> values of the structure in that dictionary?

You can't. You'll have to remove it and add a new, altered version under the
same key. You can solve the whole problem by getting rid of the structure
and using a class instead.


From: Jackie on
On 5/20/2010 21:42, Andrew Falanga wrote:
> I think I understand. So, more importantly, how can I alter the
> values of the structure in that dictionary?
>
> Andy

I think the sensible thing to do would be either
dict1["key1"] = new Struct1(Convert.ToInt32(xmlText));

or change Struct1 into a class instead of struct, and use your existing
code.