Mark Needham

Thoughts on Software Development

C#: A failed attempt at F#-ish pattern matching

with 2 comments

A few weeks ago we had some C# code around calcuations which had got a bit too imperative in nature.

The code looked roughly like this:

public class ACalculator
{
	public double CalculateFrom(UserData userData)
	{
		if(userData.Factor1 == Factor1.Option1)
		{
			return 1.0;
		}
 
		if(userData.Factor2 == Factor2.Option3)
		{
			return 2.0;
		}
 
		if(userData.Factor3 == Factor3.Option2)
		{
			return 3.0
		}
		return 0.0;
	}
}

I think there should be a more object oriented way to write this code whereby we push some of the logic onto the ‘UserData’ object but it struck me that it reads a little bit like pattern matching code you might see in F#.

I decided to drive the code to use a dictionary which would store functions representing each of the conditions in the if statements:

public class ACalculator
{
	private Dictionary<Func<UserData, bool>, double> calculations;
 
	public ACalculator()
	{
    		calculations = new Dictionary<Func<UserData,bool>,double>
                       {
                           {u => u.Factor1 == Factor1.Option1, 1.0},
                           {u => u.Factor2 == Factor2.Option3, 2.0},                                       
                           {u => u.Factor3 == Factor3.Option2, 3.0}                                 
                       };	
	}	
 
	public double CalculateFrom(UserData userData)
	{
    		var calculation = calculations.Keys.FirstOrDefault(calc => calc(userData));
    		if(calculation != null)
    		{
        		return calculations[calculation];
    		}
 
    		return 0.0;
	}
}

It’s less readable than it was before and it’s not obvious that the adding of the functions to the dictionary needs to be in that order in order for it to work.

I’ve simplified the real example a bit to show the idea but I don’t think it works as the best abstraction in this situation either way although it was an interesting experiment.

Be Sociable, Share!

Written by Mark Needham

June 13th, 2010 at 10:35 pm

Posted in .NET,F#

Tagged with ,

  • Hi Mark,

    There is an old pattern-matching code for C# by Matthew Podwysocki.

    http://weblogs.asp.net/podwysocki/archive/2008/09/16/functional-c-pattern-matching.aspx

    This works fine… But now, 2010… if pattern-matching functionality is needed, I would prefer to add a F#-library and reference it from C#.

  • it was once i read on Microsoft’s website that once they were trying to match some patterns with more than a million records and it took them 3 days to complete it all, but when they did it using F# it just finished in less than an hour. Well that speaks all………..