Alex Rivera | Logout

How can I convert anonymous type to strong type in LINQ?

Asked 2009-04-29T12:58:34.157
18

I have an array of ListViewItems ( ListViewItem[] ), where I store a SalesOrderMaster object in each ListViewItem.Tag for later reference.

I have some code that right now, goes through each ListViewItem safely casts the .Tag property into a SalesOrderMaster object, then adds that object to a collection of SalesOrders, only after checking to make sure the order doesn't already exist in that collection.

The process to compare sales orders is expensive, and I would like to convert this to a LINQ expression for clarity and performance. ( I also have the Parallel Extensions to .NET Framework 3.5 installed so I can use that to further improve LINQ performance)

So without further ado: This is what I have, and then what I want. ( what I want won't compile, so I know I am doing something wrong, but I hope it illustrates the point )

What I have: ( Slow )

foreach (ListViewItem item in e.Argument as ListViewItem[])
            {
                SalesOrderMaster order = item.Tag as SalesOrderMaster;
                if ( order == null )
                {
                    return;
                }
                if (!All_SalesOrders.Contains(order))
                {
                    All_SalesOrders.Add(order);
                }
            }

What I want: ( Theory )

    List<SalesOrderMaster> orders = 
(from item in (e.Argument as ListViewItem[]).AsParallel() 
select new { ((SalesOrderMaster)item.Tag) }).Distinct();

EDIT: I know the cast is cheap, I said the "Compare", which in this case translates to the .Contains(order) operation

EDIT: Everyone's answer was awesome! I wish I could mark more than one answer, but in the end I have to pick one.

EDIT : This

Edit
Report

1 Answer

3

Like Marc Gravell said, you shouldn't access the Tag property from different threads, and the cast is quite cheap, so you have:

var items = (e.Argument as ListViewItem[]).Select(x=>x.Tag)
         .OfType<SalesOrderMaster>().ToList();

but then, you want to find distinct items - here you can try using AsParallel:

var orders = items.AsParallel().Distinct();
answered 2009-04-29T13:20:11.377

Your Answer