473,385 Members | 1,983 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Modifying List items (generics)

For a declaration like:

List<MyTypeitems = ...

where MyType is a struct, attempt to modify an item with

items[0].member = something;

fails with the message:

Cannot modify the return value of
'System.Collections.Generic.List<MyType>.this[int]' because it is not a
variable (CS1612) - E:\project\MainForm.cs:189,8

While searching the documentation I haven't found a specific mention
that it *should* work, but it seems logical. How to get around the
restriction?
Mar 4 '07 #1
7 19441
Ivan Voras wrote:
For a declaration like:

List<MyTypeitems = ...

where MyType is a struct, attempt to modify an item with

items[0].member = something;

fails with the message:

Cannot modify the return value of
'System.Collections.Generic.List<MyType>.this[int]' because it is not a
variable (CS1612) - E:\project\MainForm.cs:189,8

While searching the documentation I haven't found a specific mention
that it *should* work, but it seems logical. How to get around the
restriction?
How wise of the compiler to prevent you from doing that. If it would
have let you, you would have changed the member of the copy of the value
that you requested from the list. This would have no effect at all, as
the original value in the list would be unchanged.

If you want to change the member of a struct, you have to get a copy of
the value, change the member, and replace the original value with the
changed value:

MyType temp = items[0];
temp.member = something;
items[0] = temp;

However, a struct should generally be immutable. If you have items that
you want to modify, you should make it a class instead.

--
Göran Andersson
_____
http://www.guffa.com
Mar 4 '07 #2
Göran Andersson wrote:
MyType temp = items[0];
temp.member = something;
items[0] = temp;

However, a struct should generally be immutable. If you have items that
you want to modify, you should make it a class instead.
Hmm, this reduces the usability of structs. But ok, it's probably
because [] is overloaded and returns a struct (i.e. a value) and
pointers don't exist.

Mar 4 '07 #3
Ivan Voras wrote:
Göran Andersson wrote:
>MyType temp = items[0];
temp.member = something;
items[0] = temp;

However, a struct should generally be immutable. If you have items that
you want to modify, you should make it a class instead.

Hmm, this reduces the usability of structs. But ok, it's probably
because [] is overloaded and returns a struct (i.e. a value) and
pointers don't exist.
Well, the indexer is actually not overloaded, it always returns the
value of the item. For a reference type the value is the reference, and
for value types it's the value itself. :)

--
Göran Andersson
_____
http://www.guffa.com
Mar 5 '07 #4
On Mar 4, 2:44 pm, Göran Andersson <g...@guffa.comwrote:
Ivan Voras wrote:
For a declaration like:
List<MyTypeitems = ...
where MyType is a struct, attempt to modify an item with
items[0].member = something;
fails with the message:
Cannot modify the return value of
'System.Collections.Generic.List<MyType>.this[int]' because it is not a
variable (CS1612) - E:\project\MainForm.cs:189,8
While searching the documentation I haven't found a specific mention
that it *should* work, but it seems logical. How to get around the
restriction?

How wise of the compiler to prevent you from doing that. If it would
have let you, you would have changed the member of the copy of the value
that you requested from the list. This would have no effect at all, as
the original value in the list would be unchanged.

If you want to change the member of a struct, you have to get a copy of
the value, change the member, and replace the original value with the
changed value:

MyType temp = items[0];
temp.member = something;
items[0] = temp;

However, a struct should generally be immutable. If you have items that
you want to modify, you should make it a class instead.
Sorry, probably slightly off topic, but I don't consider that the best
advice. Certainly you should think long and hard before creating a
mutable struct, precisely because of the behaviour the OP just
observed: they act in ways that aren't intuitive to the casual C#
programmer.

I would be more inclined to say the following: "If you have items that
logically should be structs, but you want to be able to modify them,
then realize that allowing structs to be modified in place is just
syntactic sugar for adding another constructor. Consider doing that
instead."

Viz:

structValue.Member = newValue;

is equivalent to:

structValue = new MyStruct(structValue, newValue);

A bit more typing, perhaps, and a few more bytes get moved around, but
nothing earthshaking.

Some examples of mutable structs in the .NET Framework (which cause no
end of consternation if this newsgroup is anything to go by) are Point
and Rectangle. The posts asking why you can't do this:

myForm.Location.X = 5;

seem to have died down lately, but I'm waiting for them to flare up
again.

Anyway, I don't consider it a good idea to decide between using struct
and class based on whether you think the thing should be mutable. IMHO
it has much more to do with semantics, in particular what I refer to
as "whether the thing has an identity."

Mar 5 '07 #5
Bruce Wood wrote:
On Mar 4, 2:44 pm, Göran Andersson <g...@guffa.comwrote:
>Ivan Voras wrote:
>>For a declaration like:
List<MyTypeitems = ...
where MyType is a struct, attempt to modify an item with
items[0].member = something;
fails with the message:
Cannot modify the return value of
'System.Collections.Generic.List<MyType>.this[int]' because it is not a
variable (CS1612) - E:\project\MainForm.cs:189,8
While searching the documentation I haven't found a specific mention
that it *should* work, but it seems logical. How to get around the
restriction?
How wise of the compiler to prevent you from doing that. If it would
have let you, you would have changed the member of the copy of the value
that you requested from the list. This would have no effect at all, as
the original value in the list would be unchanged.

If you want to change the member of a struct, you have to get a copy of
the value, change the member, and replace the original value with the
changed value:

MyType temp = items[0];
temp.member = something;
items[0] = temp;

However, a struct should generally be immutable. If you have items that
you want to modify, you should make it a class instead.

Sorry, probably slightly off topic, but I don't consider that the best
advice.
That depends on how deep you want to go into the matter. I think that
it's good advice for anyone who doesn't really know the difference
between a struct and a class.

Perhaps I should have added a "in most cases" in the advice about making
it a class. That would suggest that there is more to learn about the
matter to be able to make a definitive decision in every case.
Certainly you should think long and hard before creating a
mutable struct, precisely because of the behaviour the OP just
observed: they act in ways that aren't intuitive to the casual C#
programmer.

I would be more inclined to say the following: "If you have items that
logically should be structs, but you want to be able to modify them,
then realize that allowing structs to be modified in place is just
syntactic sugar for adding another constructor. Consider doing that
instead."
I don't think that this really contradicts my advice. Most items that
you want to modify shouldn't logically be structures anyway.

However, the part about modifying structures being syntactic sugar for a
constructor only applies if you modify the entire value of the
structure, and in that case it should always be done using a constructor.
Viz:

structValue.Member = newValue;

is equivalent to:

structValue = new MyStruct(structValue, newValue);

A bit more typing, perhaps, and a few more bytes get moved around, but
nothing earthshaking.
Especially if the suggested size limit for structures of 16 bytes is
followed. :)
Some examples of mutable structs in the .NET Framework (which cause no
end of consternation if this newsgroup is anything to go by) are Point
and Rectangle. The posts asking why you can't do this:

myForm.Location.X = 5;

seem to have died down lately, but I'm waiting for them to flare up
again.
They surely will. Making a structure mutable will always cause problems
for people unaware of the problems that it introduces.
Anyway, I don't consider it a good idea to decide between using struct
and class based on whether you think the thing should be mutable. IMHO
it has much more to do with semantics, in particular what I refer to
as "whether the thing has an identity."
Good advice. I guess that the basis for the decision depends on how you
are accustomed to think about data.

--
Göran Andersson
_____
http://www.guffa.com
Mar 5 '07 #6
Bruce Wood wrote:
Sorry, probably slightly off topic, but I don't consider that the best
advice. Certainly you should think long and hard before creating a
mutable struct, precisely because of the behaviour the OP just
observed: they act in ways that aren't intuitive to the casual C#
programmer.
....or to programmers coming from other languages...
I would be more inclined to say the following: "If you have items that
logically should be structs, but you want to be able to modify them,
then realize that allowing structs to be modified in place is just
syntactic sugar for adding another constructor. Consider doing that
instead."
While I accept there are situation that benefit from unmutable structs,
they are few and far between. So, for now, since I'm thinking in terms
of mutable structures, I'll just make them classes.
Some examples of mutable structs in the .NET Framework (which cause no
end of consternation if this newsgroup is anything to go by) are Point
and Rectangle. The posts asking why you can't do this:

myForm.Location.X = 5;

seem to have died down lately, but I'm waiting for them to flare up
again.
.... because you must admit that doing it that way looks very
straightforward :)
Anyway, I don't consider it a good idea to decide between using struct
and class based on whether you think the thing should be mutable. IMHO
it has much more to do with semantics, in particular what I refer to
as "whether the thing has an identity."
Maybe on a higher level of thinking about it, yes, but C# is still a
more down-to-earth language. I was very surprised with the decision to
make "structs" have methods, constructors, etc, instead of making them
just be light-weight containers for data like they're mostly used (in
other languages).
Mar 5 '07 #7
On Mar 5, 10:05 am, Ivan Voras <ivoras@__fer.hr__wrote:
Bruce Wood wrote:
Sorry, probably slightly off topic, but I don't consider that the best
advice. Certainly you should think long and hard before creating a
mutable struct, precisely because of the behaviour the OP just
observed: they act in ways that aren't intuitive to the casual C#
programmer.

...or to programmers coming from other languages...
I would be more inclined to say the following: "If you have items that
logically should be structs, but you want to be able to modify them,
then realize that allowing structs to be modified in place is just
syntactic sugar for adding another constructor. Consider doing that
instead."

While I accept there are situation that benefit from unmutable structs,
they are few and far between. So, for now, since I'm thinking in terms
of mutable structures, I'll just make them classes.
A friendly warning: struct to class (or vice versa) is a big jump in
C#. It fundamentally changes the semantics of the thing you're
defining. "I'll just make them classes" may be a fair statement in
other languages, but in the .NET world it sounds scary.

I don't want to rehash a lot of discussion that's already gone on
here, but consider the Point structure in the Framework. What would be
the difference between a Point class and a Point struct? I claim that
the main (conceptual) difference is that the former has _identity_, or
can have identity, while the latter does not. That is, if you have a
Point class then you can talk about "this point" versus "that point"
even if they have the same coordinates. You could give a Point a UID
and it would make some sense. In the latter case, you're saying that
Point is a value, that there is no concept of "this point 5, 5" versus
"that point 5, 5" any more than there is a concept of "this integer
15" versus "that integer 15". 15 is just a value, and as such has no
identity other than its value.
Some examples of mutable structs in the .NET Framework (which cause no
end of consternation if this newsgroup is anything to go by) are Point
and Rectangle. The posts asking why you can't do this:
myForm.Location.X = 5;
seem to have died down lately, but I'm waiting for them to flare up
again.

... because you must admit that doing it that way looks very
straightforward :)
Oh, absolutely it does. The problem is that what appears
straightforward isn't, which is why I tend to avoid mutable structs.
Anyway, I don't consider it a good idea to decide between using struct
and class based on whether you think the thing should be mutable. IMHO
it has much more to do with semantics, in particular what I refer to
as "whether the thing has an identity."

Maybe on a higher level of thinking about it, yes, but C# is still a
more down-to-earth language. I was very surprised with the decision to
make "structs" have methods, constructors, etc, instead of making them
just be light-weight containers for data like they're mostly used (in
other languages).
Do you know C++? If you do, think about it this way: in C++ you have
to make a value-versus-reference decision every time you declare a
variable, and every time you pass something to a method. Do you
declare it as Foo f, or Foo *f? Do you want to store the value, or a
reference to that value?

In C#, you make that decision once for a type, when you define it. If
it's a class, then every variable declaration is, effectively, Foo *f.
If it's a struct, then every variable declaration is Foo f.

Mar 5 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Peter Collinson | last post by:
Hi... Is there any way to style a List Item a different color and size than the <LI> in an Ordered List? I'd like a red super-script number and a dark blue text in a page's footnotes. And...
2
by: Unknown User | last post by:
How can I separate list items displayed inline by vertical bars | ? If I use a background image that simulate a vertical bar, and I put this bg image behind each list item, the last list item will...
2
by: deepakp | last post by:
Hi, I'm trying to create a site index page. The page layout will consist of a header, left navigation and content display. The left navigation and content display should look like the image file...
1
by: RSH | last post by:
Hi, I have a situation where I need to add several "Hidden" properties to list items in a dropdownlist. By default the DropDownList item has two properties with regards to the listitems...
0
by: John Dalberg | last post by:
using VS 2005. I have an unordered list with list items which are displayed horizontally. Some of the list items have hyper links and some have checkboxes. The problem is that the...
5
pezholio
by: pezholio | last post by:
Hi, I've got an inline list with a label and checkbox in each list item, each item comes from a MySQL database and, chances are that, in future, the list will become longer. My problem is that...
4
by: Keith Hughitt | last post by:
For example, If you have a list: <ul> <li>item 1 is short.</li> <li>item 2 is a little bit longer</li> </ul> regardless of the size of the contents of each list item, the element
0
by: c0mrade | last post by:
I have a problem with getting the list items, below is my hibernate code, after that code there is my method ..and below that is my junit test. How can I make sure that query is executing properly,...
16
Frinavale
by: Frinavale | last post by:
What I'd like to do is take a list and display it's items in a circle. For example (the order of the in the circle doesn't matter..except for Item1, it has to be at the top): Item1 ...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.