| Joe's profileJoe MayoBlogLists | Help |
|
March 27 Speaking at New Mexico .NET User GroupOn Thursday, 4/2/09, I'll be speaking at the New Mexico .NET User Group. It will be one of my favorite topics, Practical LINQ. They'll be giving away a copy of my latest book, LINQ Programming, too. If you can make it, stop by, say "Hi!", and we'll have a great time talking about LINQ and .NET development. March 26 Initial Thoughts on RIA ServicesAt Mix 09, Microsoft unveiled RIA Services. Subsequent blog entries from Nikhil Kothari and Brad Abrams provide good introductions. In a nutshell, RIA Services is a framework for making it easy to build a middle-tier for RIA applications, such as Silverlight. RIA Services makes it easy to communicate with the server and provides other essential services, such as validation and asynchronous processing. Not that you can’t do this today with Web Services, but RIA Services does a lot of this work for you. In my case, it also lets me code business logic the way I’m accustomed, with business objects, yet does all of the plumbing work that I really don’t want to do. If you’re interested, download the bits and check them out. Remember, this is Early Beta and you should install it on either a virtual machine or a computer designated just for test software. March 10 Brad Abrams on LINQ SupportIn his blog post, Framework Design Guidlines: LINQ Support, Brad Abrams say's "DO implement IEnumerable<T> to enable basic LINQ support"; This is very good advice for anyone building a framework, API, or custom collection. I was recently using a 3rd party API where the collections did not implement IEnumerable<T> or IEnumerable. Even if they are IEnumerable (non-generic) you can still use the collection with LINQ like this: customerArrayList.Add(new Customer { Name = "Jack" });
customerArrayList.Add(new Customer { Name = "Allison" });
var customers =
from Customer cust in customerArrayList
where cust.Name.EndsWith("on")
select cust;Console.WriteLine(cust.Name)); customers.ToList().ForEach(cust => var customerArrayList = new ArrayList(); If you've become accustomed to using LINQ to manipulate collections, you'll definitely feel like you're missing something without it. In my case, I wanted to do set operations with query operators like Except and Union. Here's a summary of what the 3rd party API looked like:
Each of the collection classes implements a separate interface, which is key to finding a solution for using LINQ. Here's an example of the interface:
public interface ICustCollection{ Customer GetAt(int index); int GetCount(); } Notice that the interface doesn't have standard .NET IEnumerable members like MoveNext and Count. Here's an implementation of that interface: public class CustomCustCollection : ICustCollection
{ public Customer GetAt(int index) { // whatever internal implementation they have // - could possibly be from a COM interop scenario return new Customer(); } public int GetCount() { return 1; } } The preceding code isn't a full implementation and only serves as stub code to support what I'm going to show you later. With this API, you would use the following for loop to access the contents of the collection:
ICustCollection custColl = new CustomCustCollection();
// add some stuff to cust Coll for (int i = 0; i < custColl.GetCount(); i++) { // do something with custColl, // assuming it has members } If you're accustomed to being able to use foreach or (better) LINQ, the code above is probably pretty ugly and cumbersome, especially when you have some serious filtering or collection manipulation to do. So, I decided that I wanted these collection classes to be IEnumerable<T> and solved the problem with Extension Methods. Here's how I added an extension method to ICustCollection, so that I could translate the results into List<T>, which is IEnumerable<T>: public static class ThirdPartyApiCollectionExtension
{ { var custList = new List<Customer>(); // build a List<CustomCustCollection> from custs for (int i=0; i < custs.GetCount(); i++) { custList.Add(custs.GetAt(i)); } return custList; } } Notice that both the class, ThirdPartyApiCollectionExtension, and the method, ToList, are static. Also, notice that the first parameter (only parameter in this case) is ICustCollection, modified with the this keyword to specify that ToList extends ICustCollection. The implementation of ToList simply extracts everything from custs and returns it as a List<Customer>. Now, I can use LINQ on the data like this: ICustCollection custColl2 = new CustomCustCollection();
List<Customer> custList = custColl2.ToList();
var newCustomers = If you follow Brad Abram's advice, you'll make it easy for people to use your API. Of course, if you're on the receiving end of a non-IEnumerable<T> API, you can use the work-around above. |
|
|