Could you explain to me why after executing the following code the Selected
property is not updated to true
?
The ListItem
type used comes from System.Web.UI.WebControls
namespace and is a class (not a struct.) I believed the FirstOrDefault
function returns a reference to an instance which I can update and pass around in the items
enumerable.
// produce list items out of the communities
IEnumerable<ListItem> items = communities.Select(community => new ListItem(community.Name, community.Id.ToString()));
// mark the right list item as selected, if needed
if (platform.CommunityId > 0)
{
string strCommunityId = platform.CommunityId.ToString();
ListItem selectedItem = items.FirstOrDefault(item => item.Value == strCommunityId);
if (selectedItem != null) selectedItem.Selected = true;
}
// now items do not store any updated item!
Is that because the enumerator is executed each time a foreach
is called and thus creating new items instead of returning the set containing the item I updated?
The problem is that IEnumerable
is not repeatable. You are performing the projection (community => new ListItem
) every time it is enumerated - hence it is a new ListItem
each time. Select
is a non-buffered deferred projection.
You can fix everything here with the simple addition of a .ToList()
to force the data into a single list;
var items = communities.Select(
community => new ListItem(community.Name, community.Id.ToString())
).ToList();
Now that the data is in the list, you can loop over the list any number of times - it'll always be the same items, and changes will be retained.
Your problem is that
IEnumerable<ListItem> items = communities
.Select(community => new ListItem(community.Name, community.Id.ToString()));
creates an IEnumerable that's lazily evaluated -- that is, every time it is enumerated, the original communities
sequence is re-enumerated and your Select
projection is re-executed per item in that sequence.
If you stick a .ToList()
at the end, changing the line to:
IEnumerable<ListItem> items = communities
.Select(community => new ListItem(community.Name, community.Id.ToString()))
.ToList();
you will observe a different result. While it is still an IEnumerable
, it will no longer be a lazily evaluated one, and the changes you make in it will be observable in later iterations over the same IEnumerable
.
It happens, because you use Select
:
IEnumerable<ListItem> items = communities
.Select(community => new ListItem(community.Name, community.Id.ToString()));
which creates new objects every time you iterate through items.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With