What Is Readable

So a couple of posts I read recently have been about readability of Linq, more so Linq query expressions versus the Linq methods. Don’t know what I mean?

Expression:

var result = from knowledge in Sean
             select knowledge.Linq;

As opposed to:

var result = Sean.Select(knowledge => knowledge.Linq);

Personally I would replace the lambda expression with a Func, but I can live with it right now. Anywho, the argument is that the first looks better than the second. I really don’t see this as a looks problem, but a useage problem. Fact is, they both have their uses and you should know how to read both. Why is that? Well here’s an example CAUSE I KNOW YOU WANT ONE!

One of my earlier posts had to do with solving the FizzBuzz thing with Linq where I gave you this bad ass solution:

 var result =
      listToConvert
      .Where(WhereBothDivisible(fizzNumber, buzzNumber))
      .Select(selectKeyValuePair("FizzBuzz"))
      .Concat(
            listToConvert
            .Where(WhereBuzzDivisable(fizzNumber, buzzNumber))
            .Select(selectKeyValuePair("Buzz")))
            .Concat(
                  listToConvert
                  .Where(WhereFizzDivisable(fizzNumber, buzzNumber))
                  .Select(selectKeyValuePair("Fizz")))
                  .Concat(
                         listToConvert
                        .Where(WhereNeitherDivisable(fizzNumber, buzzNumber))
                        .Select(selectKeyValuePair("Nothing")));

As you can see, I’ve used both Func fields and methods to return Funcs to clean up how this would look. I’ll even show what it would look like without this approach:

var result = listToConvert.Where(currentItem =>
             IsDivisible(currentItem, fizzNumber) && IsDivisible(currentItem, buzzNumber)
             ).Select(currentItem => new KeyValuePair(currentItem, "FizzBuzz")).Concat(...

Now I can totally admit that this second one I am showing is just ouch. So the first lesson to be learn is that Funcs and Methods that return Funcs can significantly clean up the Linq Method approach.

Now you could do the same with expressions:

 var fizzBuzz = from currentNumber in listToConvert
                where WhereBuzzDivisable(fizzNumber, buzzNumber)
                select selectKeyValuePair("FizzBuzz");

 var buzz = from currentNumber in listToConvert
            where WhereBuzzDivisable(fizzNumber, buzzNumber)
            select selectKeyValuePair("Buzz");

 var fizz = from currentNumber in listToConvert
            where WhereFizzDivisable(fizzNumber, buzzNumber)
            select selectKeyValuePair("Fizz");

var neither = from currentNumber in listToConvert
              where WhereNeitherDivisable(fizzNumber, buzzNumber)
              select selectKeyValuePair("Fizz");

Ok so nice and pretty, but now what? Concatenation. This is where is gets ugly:

  fizzBuzz.Concat(fizz.Concat(buzz.Concat(neither))));

OR

 var fizzBuzz = from currentNumber in listToConvert
                where WhereBuzzDivisable(fizzNumber, buzzNumber)
                select selectKeyValuePair("FizzBuzz")
                .Concat(
                     from currentNumber in listToConvert
                     where WhereBuzzDivisable(fizzNumber, buzzNumber)
                     select selectKeyValuePair("Buzz"))
                     .Concat(....);

See what I’m getting at? The non expression one is looking a bit better now or maybe this is a fight to see which is less fugly. Now I admit that this may not be the best FizzBuzz solution, but it gives an example or where the Linq queries can go very wrong.

Dynamic Linq: OrderBy Using a String for a Property Name

Now this is kind of dangerous to do since there is no compile time check (Like most things set in markup) but say you want to sort a collection, using the Linq extension methods, but you don’t know what you what to sort on at any given time. On top of that, you have a datagrid and a bunch of sort expressions to deal with. Now you could do something like create a hashtable full of lambda expressions that the key is the sort expression:

Dictionary<String, Func<User, IComparable>> list;

userList = User.GetUserList();
list = new Dictionary<String, Func<User, IComparable>>();
list.Add("UserName", currentUser => currentUser.UserName);
list.Add("UserID", currentUser => currentUser.UserID);
userList.OrderBy(list["UserID"]);

Works just fine, and might be preferable to what I’m about to show. OooOoOO sound eerie?

//This is just to get the property info using reflection.  In order to get the value
//from a property dynamically, we need the property info from the class
public static PropertyInfo[] GetInfo<K>(K item) where K : class
{
  PropertyInfo[] propertyList;
  Type typeInfo;

  typeInfo = item.GetType();
  propertyList = typeInfo.GetProperties();

  return propertyList;
}

//This is the dynamic order by func that the OrderBy method needs to work
public static IComparable OrderByProperty<T>(String propertyName, T item)
  where T : class
{
  PropertyInfo[] propertyList;

  propertyList = GetInfo(item);

  //Here we get the value of that property of the passed in item and make sure
  //to type the object (Which is what GetValue returns) into an IComparable
  return (IComparable)propertyList.First(currentProperty
    => currentProperty.Name == propertyName).GetValue(item, null);
}

And use:

//This takes the current user and calls the OrderByProperty method which in turn
//gives us the Func OrderBy is requesting.
var test = userList.OrderBy(currentUser
  => DynamicPropertySort.OrderByProperty("UserID", currentUser)).ToList();

Ok so what the hell? I mean intellisense on the OrderBy method doesn’t give much help. Func<<User, TKey>>. Yeah ok. So basically the return type is open. Well this kind of sucks right? Because I would have to return a Func that already knows the return type. (Be it string, int, ect) Of course, this would mean we would have to handle each sort expression in code. NOT VERY DYNAMIC IS IT? Well f that. Truth is, what the order by is looking for is a Func that takes in a User and returns something it can compare. This is where IComparable comes in.

The OrderBy has to take the returned value, say UserID which is an int, and figure out how to compare it to another value. Pretty simple. So as long as the property you are ordering by uses IComparable, you’re good to go. Pretty nice huh?

Now I would suggest, if you use this (HAHAHAHA), is to cache a dictionary of the property info with the class type as the key so that you don’t have to use as much reflection everytime. I just didn’t put that in.

U U USING

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

More Fun With Linq

Say you have a class named BannedProgram and it has a collection of DayOfWeek and a string ProcessName. Now the collection of DayOfWeek is basically a way to set the days of the week it’s banned. With this you want to create a collection of these BannedPrograms, each with their own names and days they are banned. Simple, I know.

Next you have a list of processes that are currently running and you want to get all the processes that match the names in the BannedPrograms list AND if the current day is a banned day.

First you need the day checked function:

private static Func<DayOfWeek, Boolean> dayIsToday =
  currentDay => currentDay == DateTime.Now.DayOfWeek;

Then you need the method to get the banned processes that are currently running:

private static Process[] GetBannedProcesses(BannedProgram[] programs, Process[] processes)
{
  var processList = from process in processes
  where
  (
    from program in programs
    where program.DaysBanned.Any(dayIsToday)
    select program.ProcessName
  ).Contains(process.ProcessName)
  select process;

  return processList.ToArray();
}

What this is doing:

Well if you look at this:

from program in programs
where program.DaysBanned.Any(dayIsToday)
select program.ProcessName

This is going to grab any BannedProgram that has a DayOfWeek that matches today and it will select only it’s name. This will give you a list of names of the BannedProcesses that can not be played today.

var processList = from process in processes
where
(
  from program in programs
  where program.DaysBanned.Any(dayIsToday)
  select program.ProcessName
).Contains(process.ProcessName)

This checks to see if any of the currently running processes have a name that matches a name in the banned program list.

And now you have a list of processes to kill. Yay. Not sure this is a big deal, just thought it was a fun example of using linq and subselects.

USING???

using System;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Windows.Forms;

Solve FizzBuzz Using Linq Extension Methods

So if you haven’t heard of the FizzBuzz test, it’s basically taking in a list of numbers and figuring out if they are divisible, cleanly, by two numbers. Say you have 3 and 5 and this is your list:

1

3

5

10

15

If the number is divisible by 3, then return the Fizz string. If the number is divisible by 5, return a Buzz string. If it’s divisible by both, then return FizzBuzz.

1

Fizz

Buzz

Buzz

FizzBuzz

Pretty simple and in actuality pretty easy to do with old C# tools, but I wanted to do this with Linq. With the use of Funcs, Actions, and Linq extension methods it can be done fairly easily. Technically you can do the whole thing in one line if you don’t want to bother with refactoring.

I have no idea how to format this cleanly, so sorry if the format is confusing. Basically it is take a list, get the ones you want, concatenate it with the next list.

public static IList<KeyValuePair<Int32, String>> ConvertListOfIntegersWithLinqMethods(IList<Int32> listToConvert, Int32 fizzNumber, Int32 buzzNumber)
{
var result =
  listToConvert
    .Where(WhereBothDivisible(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("FizzBuzz"))
    .Concat(
  listToConvert
    .Where(WhereBuzzDivisable(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("Buzz")))
    .Concat(
  listToConvert
    .Where(WhereFizzDivisable(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("Fizz")))
    .Concat(
  listToConvert
    .Where(WhereNeitherDivisable(fizzNumber, buzzNumber))
    .Select(selectKeyValuePair("Nothing")));

 return result.ToList().OrderBy(currentItem => currentItem.Key).ToList();
}

Using these:

private static Func<Int32, KeyValuePair<Int32, String>> selectKeyValuePair(String value)
{
 return currentItem => new KeyValuePair<Int32, String>(currentItem, value);
}

private static Func<Int32, Boolean> WhereBothDivisible(Int32 fizzNumber, Int32 buzzNumber)
{
 return  currentItem => IsDivisible(currentItem, fizzNumber) && IsDivisible(currentItem, buzzNumber);
}

private static Func<Int32, Boolean> WhereFizzDivisable(Int32 fizzNumber, Int32 buzzNumber)
{
 return currentItem => IsDivisible(currentItem, fizzNumber) && !IsDivisible(currentItem, buzzNumber);
}

private static Func<Int32, Boolean> WhereBuzzDivisable(Int32 fizzNumber, Int32 buzzNumber)
{
 return currentItem => !IsDivisible(currentItem, fizzNumber) && IsDivisible(currentItem, buzzNumber);
}

 private static Func<Int32, Boolean> WhereNeitherDivisable(Int32 fizzNumber, Int32 buzzNumber)
{
 return currentItem => !IsDivisible(currentItem, fizzNumber) && !IsDivisible(currentItem, buzzNumber);
}

And now for Contravariance

Take the classes in the last post (First, Second, Third) and assume they are exactly the same in this example.

In Covariance, we learned that whatever variable to you set equal to the return of a method has to be equal in type of larger. Or in other words, it has to have equal or less functionality.

  Second second = ReturnThird();  //OK since second has less functionality

  Third third = ReturnSecond(); //BAD since third has more functionality

Now I think you can guess what Contravariance is, but if you can’t it’s ok. Most likely you’re a tool just like me. Contravariance is the movement from small to large meaning that the type must be equal to or larger than. Following the “in other words” manor, it has to have equal or more functionality.

Now small note before I go on, saying that it has to have more/less functionality can be somewhat dangerous. After all, Third could inherit from Second and add no functionality, but I find this is an easier way to think of it. I suppose another way of thinking of it is that with Covariance the return type has to have equal or more knowledge. Meaning, Second has full knowledge of what First is, but Second has no idea what Third is.

Anywho, onto some examples. Say we take the FillX methods and add something to it.

  private void FillFirst(First firstToFill)
  {
    firstToFill.FirstOutput = "";
  }

  private void FillSecond(Second secondToFill)
  {
    secondToFill.SecondOutput = "";
  }

  private void FillThird(Third thirdToFill)
  {
    thirdToFill.ThirdOutput = "";
  }

Right off the bat you might notice that if methods allowed Covariance with parameters, you’d be in trouble. After all, if FillThird allowed parameter covariance, you could pass in a First object. What what that object do with ThirdOutPut? As things are, you would have a bad day. Lucky for you, at least if you aren’t adamant about wanting Covariance in parameters, this can’t happen.

Well shoot, I just gave away the fun of this post. Oh well, I’ll keep going in case you just have more time.

  Action<First> fillFirstAction = FillFirst;
  //No problems here since FillFirst expects a First

  Action<Second> fillSecondAction = FillFirst;
  //Still no problems although this may look odd.  But remember, FillFirst
  //just needs an object that : First, it doesn't care if the object
  //has more functionality than first.
  //
  //The FillFirst method uses the FirstOutput property and by inheritance
  //the Second being passed in has said property

  Action<Second> fillThirdAction = FillThird;
  //Not gonna happen.  The FillThird expects a third or smaller object.  Since
  //Third : Second, third is smaller than second.  Implications?  Look in the 
  //FillThirdMethod
  //
  //The method expects the object to have the ThirdOutput property which means
  //Second has to inherit from Third.  We know this to be untrue.

So basically Contravariance is used with parameters in methods to guarantee the object being passed in has at least the functionality used within the method.

Apparently there was a problem in the lobby so there will be no refreshments served tonight.

And then you hit the wall.

So as this dynamic nonsense continues, there is a sticking point to how much fun I can have. The wall? Anonymous types and generic declarations.

Here’s the old:

  Func<User, Int32> selectUserID = currentUser => currentUser.UserID;

Great if I want to select userIDs, but what if I want UserIDs AND UserNames… Easy right?

 userList.Select(currentUser => new { currentUser.ID, currentUser.UserName });

Now this is the old way, but I want the new way… IE the Func way. Problem is here

  Func<User, EHH??> selectUserID = currentUser =>  new { currentUser.ID, currentUser.UserName };

You see, there’s a problem. What the hell do I put at the return type? Fact is, without creating a method that passes back a Func or a class that has UserName and UserID properties, I’m screwed. Now from what I read here I think I get it. First take the func:

  Func<K, T>

I have K and T that the compiler has to figure out what they are. Well it’s safe to say in the example User is K, but what is T? Well it has to figure that out from the Lamdba expression. The lambda expression has no idea what it is because it’s an anonymous type. So why not just use var?

  Func<User, var>

Seems easy enough. I don’t have to know the type because of var right? Wellll problem is the compiler is looking at the lambda expression to figure out what var will be. Mr. Lambda expression can’t really figure out the type either. Enter the wall. Currently there is no way around this without methods or classes created. Supposedly there are things called Mumble Types on the way that will solve this problem.

When is a field not a field?

Ok so for the last few things I’ve been showing a more dynamic approach to linq queries , mostly dealing with collections rather than say linq to sql. Now take the new method:

public List<K> SelectFromUserList<K, L>(Func<User, K> selectMethod, Func<User, L> orderBy, List<User> userList)
{
    List<K> userList = new List<K>();
    userList = userList.OrderBy(orderBy).Select(selectMethod).ToList();

    return userList;
}

and the call was this:

  List<String> newList = userList.Select(selectUser => selectUser.Name, orderUser => orderUser.ID, userList);

Let’s say you have two needs, selecting all the userNames and all the IDs. You could go ahead and call that method twice and inserting the lambda expressions. But let’s say you want to be able to mix and match things. Say select user names and order by user id or maybe select user names and order by use names. Well there’s a solution to avoid rewriting the lambda expressions:

  Func<User, Int32> selectUserID = currentUser => currentUser.UserID;
  Func<User, String>selectUserName = currentUser => currentUser.UserName;

  Func<User, Int32> orderByUserID = currentUser => currentUser.UserID;
  Func<User, String> orderByUserName = currentUser => currentUser.UserName;

What the? See a while ago I had a method to pass back the expression, but in this case there’s nothing to create the expression from (a passed in parameter) since they are really simple expressions. How would I use them?

  List<Int32> userIDs;
  List<User> userList;
  List<String> userNames;
  userIDs = SelectFromUserList(selectUserID, orderByUserID, userList);
  userNames = SelectFromUserList(selectUserName, orderByUserID, userList);

Pretty nice huh?

Adding to the Select

So in the last post there was something like this:

 public List<K> SelectUserNameList<K>(Func<User, K> selectMethod, List<User> userList)
 {
   return userList.Select(selectMethod, userList).ToList();
 }

Called by this:

 List<String> newList = userList.Select(user => user.Name, userList);

Ok so what if you want to order something? Well same idea, just another Func. But remember, a Func that can order by any type. If you look at the OrderBy method, it expects a Func<User, L> where L is just some type you are returning. If you were ordering by UserID, well that would be an integer. Problem is, like select, you don’t want to be held down by a specific type.

 public List<K> SelectFromUserList<K, L>(Func<User, K> selectMethod, Func<User, L> orderBy, List<User> userList)
 {
   List<K> userList = new List<K>();

   userList = userList.OrderBy(orderBy).Select(selectMethod).ToList();

   return userList;
 }

And the new call would be:

 List<String> newList = userList.Select(selectUser => selectUser.Name, orderUser => orderUser.ID, userList);

Now something of note is the order in which you call the methods. Remember, x.OrderBy().Select() is saying take collection X, order it by L and create a new collection of X, then select whatever you want. You can not do the reverse. Say you want to select a list of UserNames ordered by UserName. Well you can either:

1) Order the list by user name in a list of users then select the user names.

2) Select a list of user names into a list of strings, order that list by a string.

What if you want to select user names but order by user id? You can:

1) Order the list by user id and create a list of users then select the user names.

2) Select a list of user names into a list of string and… eh LOSE

Best part about:

 userList = userList.Select(selectMethod).OrderBy(orderBy).ToList();

Is that the error is somewhat misleading. It gives you the “Cannot be inferred by usage” error, not the “Idiot, you can’t order a list of Strings by UserID”. So you have to be careful on how you have things in order.

Linq query versus just a Select

Something I ran into using the Ajax.dll and AjaxMethods (Or basically the idea of being able to call a method from .cs file in javascript) is that when returning a list of Users there was difficulty in serialization. Basically, if you have a list of users that contain a list of roles that contain a list of permissions that contain seven wives with seven children with seven dogs and seven cats… Basically a lot of information. Now lazy loading should take care of this, but lets assume there is no lazy loading.(No idea what would cause that…) Well you have an awful lot to pushout to the front end. Let’s just say it can be a little sluggish. Lets assume you are just sending the list out, and you’ve already done all the querying.

You could do:

 return userList;

Which is what I was doing. Kind of slow.

You could do:

 var query = from user in userList
             select new
             {
                UserName = user.UserName,
                UserID = user.ID
             };

 return query.ToList();

Nothing wrong with that, just a bit verbose for something so simple.

You could do this:

 return userList.Select(currentItem => new { Username = currentItem.UserName, UserID = user.ID });

All in one line. Now I personally like the sql-ish linq expressions, but for this why not fit it into one line?

Match Collections Using Linq Union

So let’s say you have two lists you want to compare to see if they hold the same items, but the items are not equal reference. Now, if you are comparing two lists that have unique values to compare, Union is perfect.

List 1 { 1, 2, 3, 4, 5 }

List 2 { 2, 1, 4, 3, 5 }

As you can see, there are no repeated values in these two lists. Easy way to figure out if all the values are the same in the two lists:

  var query = (from first in firstList
            select first).Union(from second in secondlist
                                select second);

  Assert.IsTrue(query.Count() == first.Count());

Why does this work? Union combine the two lists, removing any duplicates. So if everything goes correctly, the count of the new list has to match the count of either of the olds lists. After all 5 pairs of duplicate items gets reduced to a list of 5. Now, if there is anything different between the lists the count will get screwed. Why? Because even one difference will cause an extra item to show up in the list.

List 1 { 1, 2, 3, 4, 5 }

List 2 { 1, 2, 3, 4, 6 }

Union { 1, 2, 3, 4 , 5, 6 }

And it will only get worse for every mismatch.

Real worldish example:

    var query = (from user in userListFirst
              select user.UserID).Union(from secondUser in userListSecond
                                       select second.UserID);

    Assert.IsTrue(query.Count() == userListFirst.Count());

Bonus points if you can figure out why this would fail at times. Actually, I already told you…

UsInGS

  using System;
  using System.Linq;