Home > C# > Extension Methods on Generics

Extension Methods on Generics


Sometimes when I’m coding I have the “oh wouldn’t it be nice if this was possible” moments, which turn into great moments when I find to my surprise on occasion that they are.

One such moment recently was realising that I can create extension methods against generic types – something that I had never thought about before. In hindsight of course this is possible, since a specified generic type is an actual static type.

The situation I found myself in recently was whilst coding a bit of filtering code to allow the user to set up dynamic filters. As such I needed a list of comparison operators for which I created an enumerated list as per listing 1 below.

public enum ComparisonOperator
{
    EqualTo,
    NotEqualTo,
    GreaterThan,
    LessThan,
    GreaterThanOrEqualTo,
    LessThanOrEqualTo,
    StartsWith,
    EndsWith,
    Contains,
    IsEmpty,
    IsNotEmpty
}

Since most of the fields that the user could filter on would have similar comparison operators, I found myself adding in the same bunch for each filter type, i.e. a string based field would have ‘StartsWith’, ‘EndsWith’, ‘Contains’, etc.

My “oh wouldn’t it be nice if…” moment was wouldn’t it be nice if I could create an extension method to add in default sets of comparison operators to lists, and I found that I could as per the code in listing 2.

public static class ComparisonOperatorEnum
{
    public static IList AddNumericOperators(this IList comparisonOperatorList)
    {
        return new List<ComparisonOperator>()
            {
                ComparisonOperator.EqualTo,
                ComparisonOperator.IsEmpty,
                ComparisonOperator.IsNotEmpty,
                ComparisonOperator.LessThan,
                ComparisonOperator.LessThanOrEqualTo,
                ComparisonOperator.GreaterThan,
                ComparisonOperator.GreaterThanOrEqualTo,
                ComparisonOperator.NotEqualTo
            };
    }

    public static IList AddStringOperators(this IList comparisonOperatorList)
    {
        return new List<ComparisonOperator>()
            {
                ComparisonOperator.EqualTo,
                ComparisonOperator.NotEqualTo,
                ComparisonOperator.IsEmpty,
                ComparisonOperator.IsNotEmpty,
                ComparisonOperator.Contains,
                ComparisonOperator.StartsWith,
                ComparisonOperator.EndsWith
            };
    }

    public static IList AddReferenceOperators(this IList comparisonOperatorList)
    {
        return new List<ComparisonOperator>()
            {
                ComparisonOperator.EqualTo,
                ComparisonOperator.NotEqualTo,
                ComparisonOperator.IsEmpty,
                ComparisonOperator.IsNotEmpty
            };
    }

    public static IList AddBooleanOperators(this IList comparisonOperatorList)
    {
        return new List<ComparisonOperator>()
            {
                ComparisonOperator.EqualTo,
                ComparisonOperator.NotEqualTo,
                ComparisonOperator.IsEmpty,
                ComparisonOperator.IsNotEmpty
            };
    }
}

This means that my filter definition code is now shorter and clearer, and for those of you who like such things, more fluent.

myFilteredField.ComparisonOperators = new List().AddStringOperators();

It also means that if I add in any additional comparison operators in the future, then I won’t have to hunt down any filtering code and manually add them in.

A happy C# camper.

Advertisements
Categories: C# Tags: , ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: