Using LINQ to sort a ReadOnly list

Using LINQ to sort a ReadOnly list

Old forum URL: forums.lhotka.net/forums/t/8587.aspx


ballistic posted on Saturday, February 27, 2010

I have CountryInfoList which is a ReadOnlyListBase<CountryInfoList, ICountryInfo>. This class implements both it's own interface ICountryInfoList and IReportTotalRowCount.

I am attempting to sort a list of type ICountryInfoList using LINQ, but get "Can't resolve symbol OrderBy"

I am using Dependency Injection to resolve the ICountryInfoList to the concrete implementation CountryInfoList.

var unsortedList = IoC.Resolve<ICountryInfoList>().FindActive(languageCode, args);

var query = from j in unsortedList
                        orderby j.NameByLanguage
                        select j;

If I change it from having IoC resolve the interface and instead create an instace of CountryInfoList and call it's FindActive(languageCode, args), the query will work.

It looks that by having the interface, I am removing some functionality.

Is there a specific way I am suppose to have the interface so that LINQ can work against the returned list?

 - Andy

tmg4340 replied on Sunday, February 28, 2010

LINQ is designed to work against some collection interfaces - IEnumerable<T>, IQueryable<T>, etc.  So if you want your ICountryInfoList interface to work in LINQ, it needs to derive from one of those interfaces (I would probably choose IEnumerable<T>.)  I think that also means your ICountryInfoList interface will need to be a generic interface as well.  While your IOC tool should be able to handle that well enough, that obviously changes how you work with it in your app.

HTH

- Scott

ballistic replied on Sunday, February 28, 2010

CountryInfoList uses the ReadOnlyListBase, which itself has "IEnumerable<C> Where", having  CountryInfoList inherit from ReadOnlyListBase<CountryInfoList, ICountryInfo> does provide me the functionality. However, when I start returning list of my own interface (ICountryInfoList), that's when I loose the LINQ functionality.

I tried to have my ICountryInfoList implement IEnumerable<ICountryInfo>, but obviously I need to define each of the methods in the interface (Current, Reset, MoveNext, etc).

Is there a way I can leverage the functionality built into CSLA and not have to define each of the methods in my CountryInfoList which would simple call the methods in the base class? (looks like simply implementing IReadOnlyCollection does not do it)

Sorry if these questions are obvious, but first time I try to work with interfaces (for testing purposes) and LINQ (since SortedBindingList has now been replaced by LINQ).

Thank you,
- Andy

tmg4340 replied on Sunday, February 28, 2010

You won't try to implement the interface on your ICountryInfoList interface.  You would turn it into a generic interface and have it derive from IEnumerable - something like this:

interface ICountryInfoList<T> : IEnumerable<T>

That way, you can assign ROLB-based objects to your interface, and you can also use your interface in LINQ queries.  ROLB has an implementation of IEnumerable<T> already, so everything will just work.

Where this is going to potentially "get you" is that your interface is now a generic interface, so you have to provide a type.  Given how your ROLB list is defined, that type can probably be ICountryInfo, but that's a guess - I'd have to see a little more of how you're using it to really know that for sure.  Regardless, your IOC container should be able to resolve the generic type easily enough.  But this also changes how you work with your interface in your app.

HTH

- Scott

Copyright (c) Marimer LLC