Tag Archives: C#

31 Days of Refactoring on LosTechies

August is Refactoring Month for Sean Chambers over on LosTechies.  Some of the methods he looks at are well known, some not so much, but all are worth knowing.  Check it out at http://www.lostechies.com/blogs/sean_chambers/archive/2009/07/31/31-days-of-refactoring.aspx.

Advertisements

The IEqualityComparer in action

I recently had the situation where I had a class similar to the following:

public class Item
{
    public Guid ItemID { get; set; }
    public string ItemName { get; set; }
    public IList Categories { get; set; }
}

public class Category
{
    public Guid CategoryID { get; set; }
    public string CategoryName { get; set; }
}

Data for the application was pulled out of a Linq to SQL class, working off a SQL database.  (I don’t want to get into a discussion on the semantics of my design choice – perhaps Items should be members of Categories instead of the other way around.  Just enjoy the show for now…)

What I wanted to do was to filter a Linq query from the database (containing IQueryable<Item>) for items that contained Categories with a given CategoryID.  No problems!   Just run up a Linq to SQL query to get the Category instance matching that CategoryID as follows:

var myCategory = (from c in datacontext.dbCategories
                  where c.ID == myCategoryID
                  select new Category
                  {
                      CategoryID = c.ID,
                      CategoryName = c.Name
                  }).Single();

Note that the filter as shown below won’t work on an IQueryable<Item> (due to the Contains() clause), so we’ll evaluate the incoming IQueryable<Item> as it comes in, and (for convenience) convert it back to IQueryable on the way out.  We’ll implement the method as an extension method, because we can.

public IQueryable FilterByCategory(this IQueryable qry, Category cat)
{
    return (from i in qry.ToList()        // Evaluate the qry
            where i.Categories.Contains(cat)
            select i).AsQueryable();
}

Now, this is all fine, as far as it goes.   Except for one small thing.

It didn’t work.

My result set was empty.  Always.

So what’s going on?  Basically, here’s the thing.  Have a look at the following code fragments:

int x = 7;
int y = 7;
Debug.Assert(x == y);    // Assert is true

class MyObject
{
    public int Value;

    public MyObject(int val)
    {
        Value = val;
    }
}
MyObject a = new MyObject(7);
MyObject b = new MyObject(7);
Debug.Assert(a == b);    // Assert fails!

It may seem obvious, but the reason the second Assert fails is that, despite having the same internal value, a and b are not the same! And this is the problem with my filter query above.   Despite the Category instance I received from the SQL query having the same internal values as (perhaps) a Category in the Categories property of an Item, they are not the same object and so the comparison will fail.
What we need is some way of telling .NET that two instances of an object are the same, even if they are different objects, and this is where the IEqualityComparer comes in.  We can create the following class:

class CategoryComparer : IEqualityComparer
{
    #region IEqualityComparer Members

    public bool IsEqual(Category x, Category y)
    {
        return x.CategoryID == y.CategoryID;
    }

    public int GetHashCode(Category obj)
    {
        return obj.CategoryID.GetHashCode();
    }

    #endregion
}

We have created a class that says that two instances of Category are equal when their CategoryID values match, and have based their Hash Code on the CategoryID value rather than the instance itself.  All we need to do now is to plug it in to the query, as follows:

public IQueryable FilterByCategory(this IQueryable qry, Category cat)
{
    return (from i in qry.ToList()        // Evaluate the qry
            where i.Categories.Contains(cat, new CategoryComparer())
            select i).AsQueryable();
}

Voila!  .NET is a wonderful environment, but there are always a few gotchas lying around for the unsuspecting.  Work through probelms methodically, and you’ll find there’s always a way.

Generic List ContainsOneOf

I needed a function that would return a boolean indicating if any of the values from one list appeared in another list.  I love extension methods…

public static bool ContainsOneOf<T>(this IList<T> first, IList<T> second)
{
    foreach (T item in first)
    {
        if (second.Contains(item))
            return true;
    }
    return false;
}

Remember to place this method in a public static class.

Disabling the Maximize button in WPF

I am writing a WPF application which runs as a tool-style dialog on the desktop, and needs to be able to be minimized but not maximised.  It seems that this is somthing the WPF designers didn’t quite anticipate, despite it having been pretty easy to achieve under Windows Forms.

After searching around the ‘net, I finally found some code that disabled both the minimize & maximize buttons, but took a couple shortcuts that I didn’t like (and besides, it was in VB…).

A bit of searching and a quick cleanup left me with a working result.  Catch the Loaded event of your window, and put the following code into the handler:

// Import some references
using System.Interop;
using System.Runtime.InteropServices;

// Place these inside the class definition...
[DllImport("user32.dll")]
private extern static Int32 SetWindowLong(IntPtr hWnd, Int32 nIndex, Int32 dwNewLong);
[DllImport("user32.dll")]
private extern static Int32 GetWindowLong(IntPtr hWnd, Int32 nIndex);

private const Int32 GWL_STYLE = -16;
private const Int32 WS_MAXIMIZEBOX = 0x10000;
private const Int32 WS_MINIMIZEBOX = 0x20000;

// And finally the event handler...
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    IntPtr hWnd = new WindowInteropHelper(this).Handle;
    Int32 windowLong = GetWindowLong(hWnd, GWL_STYLE);
    windowLong = windowLong & ~WS_MAXIMIZEBOX;
    SetWindowLong(hWnd, GWL_STYLE, windowLong);
}

I have included the value for WS_MINIMIZEBOX in case you need it.

Unchecking Overflows

I recently ran into a new (for me) compiler error from the following line of code:

UInt16 section_length = (UInt16)(SizeOfSection - 3);

where SizeOfSection is a UInt32.  The error messages were as follows:

1. The operation overflows at compile time in checked mode
2. Constant value '4294967293' cannot be converted to a 'ushort' (use 'unchecked' syntax to override)

Strangely, even though these were marked as compilation errors, the code compiled and ran correctly.

Anyway, the fix was (as suggested) to use the unchecked syntax:

UInt16 section_length = unchecked((UInt16)(SizeOfSection - 3));

The bizarre thing about this, though, is that other code that casts UInt32 to UInt16 didn’t produce this error, so I would be interested to know what triggered it in this case…

Get Specific Object from an Array

For the last couple of years, I’ve been writing a program to decode DVB transport streams (more info at the Multiflex site), and have recently started implementing the decoding of H.264 (MPEG-4) video streams.

One challenge I have come across is to find the last instance of a certain class of object within an array of (generic) objects, for example to find the last instance of a class of type ‘Foo’ within ‘object[] args’.

Initially, I started with something like the following:

public Foo GetFoo(object[] args)
{
    for (int i = (args.Length - 1); i >= 0; i- -)
    {
        if (args[i] is Foo)
            return args[i] as Foo;
    }
    return null;
}

This is a bit messy, however.  Now that I have come to know and love C# 3.0, LINQ and Lamda Expressions, this can be distilled down to the following:

public Foo GetFoo(object[] args)
{
    try
    {
        return args.Last(c => c is Foo) as Foo;
    }
    catch
    {
        return null;
    }
}

Such elegance!!!

(BTW: The try/catch is in there because Last() will throw an Exception if no object of type Foo exists within args)

Introduction to C# 3.0

I learnt C# 1.0 back in the early part of this millenium, then changed jobs and concentrated on C++ and ANSI C (yes, I even bought a copy of Kernighan & Ritchie).  When I switched back to C# a couple of years ago, I basically had to re-teach myself all that I knew, and since C# 2.0 was in vogue then, that’s what I learnt.

Now, while I pride myself on being an early adopter in most areas, I have managed to successfully ignore C# 3.0 until now.  Honestly, who really needs LINQ anyway?

Oops!

I found some very informative talks from TechEd on MSDN’s Spotlight site recently which do a great job of highlighting the changes in C# 3.0 and introduce LINQ and Lamda Expressions in a really easy-to-digest format.  So easy that even I was forced to think, “Crap!  Why didn’t I get into this stuff sooner?”

Anyway, here are the links:

C# 3.0: Future Directions in Language Innovation
Anders Hejlsberg
http://www.microsoft.com/emea/msdn/spotlight/sessionh.aspx?videoid=319

Microsoft Visual C# Under the Covers: An In-Depth Look at C# 3.0
Luke Hoban
http://www.microsoft.com/emea/msdn/spotlight/sessionh.aspx?videoid=710