I have been busy with a series of tasks and couldn’t find time to complete operators section. Although I had a safari account via university subscription and could read it online, I ordered a great book "C# 3.0 in a nutshell – O’Reilly – Joseph Albahari & Ben Albahari". Amazon estimate was I would get it sometime after August 11th but to my surprise I got it yesterday and maybe that has motivated me to spare extra time and write today’s (well tonight’s) blog. That is not the first book I read about C# and possibly won’t be the last but I must admit I liked it very much.
OfType: Returns the items from a sequence that are of a given type. This is especially useful with object collections where the collection can have multiple different types and ArrayList is a typical sample.
and here is the partial output in LinqPad:
With generic lists it is unlikely that you would need OfType.
Cast: Cast returns a sequence attempting to cast each member to a given type. If it can’t cast one ten it throws an error. The difference between OfType and Cast is that, Cast throws an error if it encounters an incompatible type for casting. OfType, on the other hand, ignores incompatible types and simply returns an empty sequence if it cannot cast any member.
If we try the OfType<string>() with Cast<string>() we will get an exception. Probably, Cast was added to support ArrayList and I can’t think of a good usage for it.
AsEnumerable: Upcasts a sequence to an IEnumerable sequence. Converting to an Enumerable effectively makes the sequence local and then you can apply methods that are not supported on a remote (IQueryable) source. For example Linq To SQL doesn’t support Last() but you could make the sequence local with AsEnumerable() and apply Last(). This nice sample is borrowed from LinqPad samples:
The sample is getting medical articles whose topic is "influenza" and abstract is less than 100 words. Getting articles whose topic is "influenza" is trivial and the part before AsEnumerable() does that. That part is converted to this SQL:
The tricky part is counting the words. To count words regular expression is used and that wouldn’t execute on Linq To SQL. Applying AsEnumerable() converts the sequence to a local one and makes it possible to count the words using regular expression.
AsQueryable: Converts a sequence to an IQueryable either by downcasting or by creating an IQueryable wrapper. Converted to an IQueryable you can execute the query locally or remotely.
ToArray and ToList: Convert a sequence to an array or generic list respectively. The generated array or list is a snapshot taken at the moment the query is run. That is particularly useful when a query needs to be executed often and a snapshot is sufficient.
ToDictionary and ToLookup: These operators create a snapshot dictionary of a given sequence. A dictionary is a key, element pair and you can access a member using the key as a indexer. ToDictionary creates a dictionary where sequence has a unique entry per key (typically a primary key as in a table). ToLookup on the hand looks like foreign key and there can be multiple values for the same key in a sequence. The key is used as an indexer in both.
gives this result (note how we use the unique CustomerID as a key and the particular value to "BONAP" to access a member in dictionary via indexer):
SequenceEqual: Also accepted as a quantifier operator this operator compares two sequences and returns true if the sequences have identical elements and in the same order.
This concludes the standard Linq operators. There are other extension methods that are not yet available in .Net 3.5 and since it is extensible we should expect more in the future. Happy LINQinq.