Monday, March 12, 2012

Refactoring with LINQ

So my little brother sent over the code below last week and asked me if there was a better way to do it. When I first read through it I was thinking…I can’t believe people still use the good ole to/from listbox style UI. I don’t remember the last time I had to write this code, but I’m pretty sure it was prior to LINQ.

protected void moveItems(ListControl sendingLB, ListControl receivingLB)
{
ListBox temp = new ListBox();
List<ListItem> tempList = new List<ListItem>();
Comparison<ListItem> compare = new Comparison<ListItem>(CompareListItems);
foreach (ListItem li in sendingLB.Items)
if (li.Selected && receivingLB.Items.FindByText(li.Text) == null)
receivingLB.Items.Add(li);
else
temp.Items.Add(li);
foreach (ListItem li in receivingLB.Items)
tempList.Add(li);
tempList.Sort(compare);
receivingLB.Items.Clear();
receivingLB.Items.AddRange(tempList.ToArray());
sendingLB.Items.Clear();
foreach (ListItem li in temp.Items)
sendingLB.Items.Add(li);
receivingLB.ClearSelection();
}
int CompareListItems(ListItem li1, ListItem li2)
{
return String.Compare(li1.Text, li2.Text);
}

So here’s what I came up with in my response using LINQ.

protected void moveItems(ListControl source, ListControl destination)
{
var getListItemsFrom = new Func<ListControl, List<ListItem>>
(x => x.Items.Cast<ListItem>().ToList());
var selectedItems = getListItemsFrom(source).Where(x => x.Selected);
var nonSelectedItems = getListItemsFrom(source).Where(x => !x.Selected);
var currentDestinationItems = getListItemsFrom(destination);
//Thanks Ryan for the .Except instead of the .Where(not)
currentDestinationItems.AddRange(selectedItems.Except(currentDestinationItems));
ReloadItemsFor(destination, /*with*/ currentDestinationItems);
ReloadItemsFor(source, /*with*/ nonSelectedItems);
destination.ClearSelection();
}
private void ReloadItemsFor(ListControl listControl, IEnumerable<ListItem> itemsToAdd)
{
listControl.Items.Clear();
listControl.Items.AddRange(itemsToAdd.OrderBy(x => x.Text).ToArray());
}

Basically I was able to get rid of all the for loops, sorting, adding items, and most importantly, the new version is more readable.

Shout it

kick it on DotNetKicks.com

Related Posts Plugin for WordPress, Blogger...