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

后端 未结 3 1501
南方客
南方客 2021-02-07 05:54

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

I ha

相关标签:
3条回答
  • 2021-02-07 06:17

    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();
    
    0 讨论(0)
  • 2021-02-07 06:20

    I see nobody has addressed your need to convert an anonymous type to a named type explicitly, so here goes... By using "select new { }" you are creating an anonymous type, but you don't need to. You can write your query like this:

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

    Notice that the query selects (SalesOrderMaster)item.Tag without new { }, so it doesn't create an anonymous type. Also note I added ToList() since you want a List<SalesOrderMaster>.

    This solves your anonymous type problem. However, I agree with Mark and Guffa that using a parallel query here isn't you best option. To use HashSet<SalesOrderMaster> as Guffa suggested, you can do this:

    IEnumerable<SalesOrderMaster> query = 
        from item in (ListViewItem[])e.Argument
        select (SalesOrderMaster)item.Tag;
    
    HashSet<SalesOrderMaster> orders = new HashSet<SalesOrderMaster>(query);
    

    (I avoided using var so the returned types are clear in the examples.)

    0 讨论(0)
  • 2021-02-07 06:31

    The part in that code that is expensive is calling the Contains method on the list. As it's an O(n) operation it gets slower the more objects you add to the list.

    Just use a HashSet<SalesOrderMaster> for the objects instead of a List<SalesOrderMaster>. The Contains method of the HashSet is an O(1) operation, so your loop will be an O(n) operation instead of an O(n*n) operation.

    0 讨论(0)
提交回复
热议问题