Thursday, July 17, 2008

I likz demz linq

So today I had this weird need to try creating a sort of dynamic linq thing in which I could query a User list but not have to write a Linq query for every method. I just wanted to make a method that would return the correct query that I wanted based on a simple "dynamic" where clause. Well part of the reason this should be easy is if you look at the Where extension method on an IEnumerable collection, you will see it needs a Func<T, K> where T is the type of the items in the list. So ding!, create a method that takes in a Func<User, Boolean> and puts it in them thar where clause. Then you could easily use a lambda expression to create the Func. At first you might thing something like this:
private static IQueryable<User> GetUserList(Func<User, Boolean> whereClause)
{
  var query = from user in Users
            where whereClause(user)
            select user;

  return query;
}

public static IList<User> GetUserListByUserName(String userName)
{
  return GetUserList(currentUser => currentUser.UserName == userName).ToList();
}
AND YOU WOULD BE WRONG! I only know this because... eh... I saw a friend of mine try this and it failed. Fact is, the Linq where doesn't take in a Func, but rather it expects and Expression. So no big deal right? Slap on an expression and go... except you can't keep the same syntax. (Trust me, my... friend tried) Being the absolute genius that I am, I offered my friend a solution, and it's slightly ugly:
private static IQueryable<User> GetUserList(Expression<Func<User, Boolean>> whereClause)
{
  var query = (from user in Users
            select user).Where(whereClause);

  return query;
}
Could be used like:
public static IList<User> GetUserList()
{
  return GetUserList(currentUser => true).ToList();
}
Or
public static IList<User> GetUserListByFirstName(String firstName)
{
  return GetUserList(currentUser => currentUser.FirstName == firstName).ToList();
}
Yeah, not the prettiest of things, but it is what it is. I'm not even sure this is useful yet. Still screwing around with it. Does cut down on code for easy queries. AND NOW FOR THE ASSEMBLIES!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

Monday, July 14, 2008

I ain't gettin' paid enough for this...

Remember when I said I'm not exactly great with programming terms? Well if I didn't, I am saying it now. So I saw the word "closures" today and had no idea what this was. All excited about something new, I found out that closures is just another word for anonymous methods, although it may include stuff outside that scope but I'm not sure. Anyhow, although this seemed to be yet another attack of the stupid I stumbled across something here. Basically what caught me is how value types are handled with Funcs. Take this method:
using System;
using System.Collections.Generic;
using System.Linq;

public static Func<Int32> ReturnIntegerWithinFuncReturningMethod(WhichMethod methodToReturn)
{
  Int32 integerToIncrement;
  Func<Int32> returnMethod;
  
  integerToIncrement = 0;
  returnMethod = null;
  
  switch(methodToReturn)
  {
  case WhichMethod.AddOne:
   returnMethod = new Func<Int32>(() => { return integerToIncrement += 1;} );
   break;
  case WhichMethod.AddTwo:
   returnMethod = new Func<Int32>(() => { return integerToIncrement += 2; });
   break;
}
  
 return returnMethod;
}
Let's say we test it like this:
Func<Int32> returnedMethod;
Int32 integerToCheck;

returnedMethod = ReturnIntegerWithinFuncReturningMethod(WhichMethod.AddOne);
integerToCheck = returnedMethod();
Assert.IsTrue(integerToCheck == 1, "Actual value is:" + integerToCheck.ToString());

integerToCheck = returnedMethod();
Assert.IsTrue(integerToCheck == 2, "Actual value is:" + integerToCheck.ToString());
These both pass. How does that make sense? You would think that it would return 1 both times since from first glance integerToIncrement lives outside the actual Func that is returned. You would think from this that Int32 is a reference type. When a value type is "attached" to a Func like this one is, apparently it keeps a reference to it and therefore the original Int32 is updated every time the Func is called. Something to remember.

Thursday, July 10, 2008

Guard Clause Method

So I was introduced to the idea of a "guard clause" in methods when I started my latest job. The idea is to make sure that all the passed in parameters of a method are, for example, not null. If they are, just throw an exception. This is what I have been doing:
if(someField == null)
{
throw new ArgumentNullException();
}
Well just recently I was somewhat schooled in the idea of removing if statements and creating simple methods in their steed. Now this isn't always a need, but in complex (ie annoying) nested ifs, it might help to clean things up. So in light of this, I came up with this method:

using System;
using System.Collections.Generic;
using System.Reflection;

private void ThrowExceptionIfNull<TException, TObject>(TObject objectToCheck, String message)
where TException : Exception 
where TObject : class
{
  if(objectToCheck == null)
  {
      TException exception;

      exception = Activator.CreateInstance<TException>();
      //Set the message field on System.Exception since the property is Get only
      if(message != null)
      {
          List<FieldInfo> fieldInfoList;
           FieldInfo neededInfo;
  
          fieldInfoList = new List<FieldInfo>(typeof(Exception).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
          neededInfo = fieldInfoList.Find(currentItem => String.Compare(currentItem.Name, "_message") == 0);
          //make sure that the message field is still called _message, otherwise
           //forget the message.
           if(neededInfo != null)
          {
              neededInfo.SetValue(exception, message);
          }
      }
      throw exception;
  }
}
And the use:
ThrowExceptionIfNull<ArgumentNullException, String>(someParameter, "someParameter");
Couple things to keep in mind:
  • This uses reflection to find the message field since there is no set accessor to the Message property. This could be dangerous if Microsoft decides to rename the _message field.
  • The use of reflection would usually include the caching of the field info since you don't want to keep using reflection for the same class every time. In this case, you're throwing an exception so everything is done anyhow. The cost advantage of a cache is pointless.

Wednesday, July 9, 2008

Sub Select and IN Clause faking

I have yet to find a good way to represent an IN clause in Linq, but I found this yesterday and kind of liked it. Mind you, I've used this only on two lists, not database involved. Will check what it does on the database call later. Anyhow, I needed a way to check if the records in one list are the same as the other. I'm sure there are a billion ways to do this, but I wanted a Linq way. I stumbled onto this idea when looking for a solution to something else. Basically I have two lists of users and a user contains a UserID. listOne and listTwo are both List<User>.
var query = from listOneUser in listOne
            where
            !(
                from listTwoUser in listTwo
                select listTwoUser.UserID
            ).Contains(listOneUser.UserID)
              select listOneUser;
I select all the IDs from the second list and then see if the first list has any users that don't exist in the second list. If this query gives me a list with a count greater then 0, I know that list one has at least one different item. Again, this isn't bullet proof, just a way to show the kind of IN clause.

Joining By Anonymous Types

Just found this out yesterday so I thought I would post and pass on to all two of you reading this. Suppose you have a User table and a Contacts table and you wanted to find all the users that match up with the contacts table. Now suppose there is no direct correlation. What to do? You could do something really brilliant by joining the tables together on FirstName and LastName, because we all know that there will always only be one John Smith in either table. Screw you, I couldn't think of a better example at the time.
public static List<User> GetAllUsersWithMatchingContactInformationUsingJoin()
{
  List<User> foundUsers;
          
  var query = from user in dataContext.Users
              join contact in dataContext.Contacts on new {user.FirstName, user.LastName } equals new { contact.FirstName, contact.LastName }
              select user;
          
              foundUsers = query.ToList();
          
  return foundUsers;
}
As you can see here:
join contact in dataContext.Contacts on new {user.FirstName, user.LastName } equals new { contact.FirstName, contact.LastName }
You can create a type on the fly and then compare it to another. I thought that was interesting.

Monday, July 7, 2008

I are tupid

This may be novel or really dumb, but I like it. Say you want to convert a Dictionary to a List of KeyValuePairs that are sorted by something within the dictionary Key or Value. Don't ask why, just go with it. You could do this: Where someDictionary is Dictionary<Type, string> :

List<KeyValuePair<Type, String>> dataSource = new List<KeyValuePair<Type, String>>(someDictionary);
dataSource.Sort(new SomeComparer<KeyValuePair<Type, String>>("Value", true));
To:
var query = from keyValuePair in someDictionary
          orderby keyValuePair.Value
          select new KeyValuePair<Type, String>(keyValuePair.Key, keyValuePair.Value);
SomeMethod(query.ToList());
If nothing else, you don't have to create or implement a System.Collections.IComparer class to use the .Sort method. That seems worth it. That and I think it just plain looks better, but that just me. If I am completely wrong here, refer to the title of this post. Just a thought really.

Tuesday, July 1, 2008

Filling a Private Field on a Base Class

Ok here's the next step in this testing kick. So now you have your test classes that create classes. Swell. Problem is, there are private fields on the base class of whatever class you are creating. So you're screwed, right? Not really. Now what I am about to do is nothing new. It's just basically using Reflection and FieldInfo to fill a field on a base class. Actually very easy. Here's the code for the example.

using System;
using System.Collections.Generic;
using System.Reflection;


public class UserBase
{
  private Boolean _isBaseUser;

  public UserBase()
  {
      _isBaseUser = true;
  }

  public Boolean IsBaseUser
  {
      get
      {
          return _isBaseUser;
      }
  }
}

public class MainUser : UserBase
{
  //Simple list used to "cache" the field info so reflection doesn't have to be used
        //again for a type that has already been used.
  private static Dictionary<Type, List<FieldInfo>> typeToInfoList;

  /// <summary>
        /// This is used to fill in the needed field on the passed in object.  This is done by reflection/
        /// FieldInfo.  Basically you get the field info you want off the type, then you use the info to
        /// fill the field on the object.  
        /// </summary>
        /// <param name="objectToFill">This is the object that needs the field changed.</param>
        /// <param name="fieldName">This is the name of the field.</param>
        /// <param name="value">This is the value to be set.</param>
        /// <param name="typeToCheck">This is the type of the class that the field resides.</param>
  public static void FillField(Object objectToFill, String fieldName, Object value, Type typeToCheck)
  {
      List<FieldInfo> fieldInfoList;
      FieldInfo neededFieldInfo;
      Boolean heldInfoList;

      if (typeToInfoList == null)
      {
          typeToInfoList = new Dictionary<Type, List<FieldInfo>>();
      }
      //Check to see of the list already has the field info and save that 
          //boolean for later use.
      heldInfoList = typeToInfoList.ContainsKey(typeToCheck);
      //If it is in the "cache", grab it.  If not, create a new list
          //for the passed in type.
      fieldInfoList = heldInfoList ? typeToInfoList[typeToCheck] : new List<FieldInfo>(typeToCheck.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));

     //Now just look for the needed field info in the list. 
     neededFieldInfo = fieldInfoList.Find(currentItem => currentItem.Name == fieldName);
      //Use the field info to set the value on the object.
      neededFieldInfo.SetValue(objectToFill, value);

      //Store the field info list if it isn't being stored already.
      if (!heldInfoList)
      {
          typeToInfoList.Add(typeToCheck, fieldInfoList);
      }
  }

  //Simple constructor to create the user.
  public static MainUser Create()
  {
      MainUser testUser;

      testUser = new MainUser();

      return testUser;
  }
}
That's pretty much it. What the hell is all that? Well basically you have the UserBase as the base class for the example. MainUser that in inherits UserBase. The FillField method that does all the work. And lastly, the dictionary used as a lame cache for this example. Why cache anything? Well everything you get the field info, reflection is used. This can be expensive. So why bother getting the same field info for the same type every time this method is called? Just store it somewhere so that if the same class type is passed through again, you can easily access the field info for the class without going for reflection again.

Here's an example of the use:
using Microsoft.VisualStudio.TestTools.UnitTesting;

 [TestClass]
 public class FillFieldTest
 {
     [TestMethod]
     public void FillField_CheckFieldForChange()
     {
         MainUser testUser;

         testUser = new MainUser();
         Assert.IsTrue(testUser.IsBaseUser);

         MainUser.FillField(testUser, "_isBaseUser", false, typeof(UserBase));
         Assert.IsFalse(testUser.IsBaseUser);
      
         MainUser.FillField(testUser, "_isBaseUser", true, typeof(UserBase));
         Assert.IsTrue(testUser.IsBaseUser);
     }
 }
First test is checking to see if the IsBaseUser property is true. This will be true since UserBase sets _isBaseUser to true on instantiation.

Second test is checking to see if the FillField method worked correctly.

Third test is really just to step through a second time so you can see how the quasi-caching works.