A fun note in C# on switching on enums

A blog post from ClearTax Engineering. 

A Lisp person would find this post amusing and trivial. The more lisp we learn, the more we understand what Paul Graham meant in his essays on lisp.
We use a lot of C# 3 and C# 4 features which are functional (always begging the question, why we aren’t on F#).

So ClearTax supports on the web edition 5 types of entities: Individuals, HUF (Hindu Undivided Family), Partnership Firms, Public Company, Private Company. These can generate ITR-1, 2, 3, 4S, 4, 5 and ITR-6. 

Now since we also support taxcloudindia.com which is a portal for Chartered Accountants, we are adding support for Entities such as AOP (Association of Persons), Co-Operative Societies, LLP (Limited Liability Partnerships) and so on.

public enum EntityType
        {
            Individual, 
            Minor, HUF, Firm,
            AOP, Trust, Cooperative,
            CompanyPublicInterested, CompanyPublicNotInterested
        };
This is how the Entity enum looks like.

Now our code has 50 odd places where we have to do a “switch-case” over the EntityType to do the appropriate behavior based on the specific entity. 

Now the problem with fixing all those 50 places for adding new entities is problematic — as finding all those 50 places every time we add a new entity is fraught with potential oversights and bugs. And these bugs are caught only during run-time and not compile-time. Example:

      switch (filer.baseFiler.GetEntityType())
            {
                case EntityEnum.EntityType.Individual:
                case EntityEnum.EntityType.HUF:
                    {
                        ViewBag.itrBalanceSheet = “BalanceSheetItr4”;
                        break;
                    }
                case EntityEnum.EntityType.Firm:
                    {
                        ViewBag.itrBalanceSheet = “BalanceSheetItr5”;
                        break;
                    }
                case EntityEnum.EntityType.CompanyPublicInterested:
                case EntityEnum.EntityType.CompanyPublicNotInterested:
                    {
                        ViewBag.itrBalanceSheet = “BalanceSheetItr6”;
                        break;
                    }
                default:
                    throw new NotImplementedException(“Entity Not recognized for BalanceSheet”);
            }
If you add support for a new entity, and you miss this switch-case, you going to step on the Exception and that is no fun.

So we got thinking how to do this in compile time. A chance tweet a few days ago Retweeted by Miguel de Icaza caught my eye. 

Two and two together and here’s what we get:

public static T SwitchSupported<T>(this EntityEnum.EntityType entityType, 
                                   T Individual, T HUF, T Firm, 
                                   T CompanyPublicInterested, T CompanyPublicNotInterested)
        {
            switch (entityType)
            {
                case EntityEnum.EntityType.Individual: return Individual;
                case EntityEnum.EntityType.HUF: return HUF;
                case EntityEnum.EntityType.Firm: return Firm;
                case EntityEnum.EntityType.CompanyPublicInterested: return CompanyPublicInterested;
                case EntityEnum.EntityType.CompanyPublicNotInterested: return CompanyPublicNotInterested;
                default:
                    throw new ArgumentException(“Unsupported Entity Type has been switched: ” + entityType.ToString());
            }
        }
Now we replace the above switch-case with this code:

ViewBag.itrBalanceSheet = filer.baseFiler.GetEntityType().SwitchSupported(
                                   Individual: “BalanceSheetItr4”,
                                   HUF: “BalanceSheetItr4”,
                                   Firm: “BalanceSheetItr5”,
                                   CompanyPublicInterested: “BalanceSheetItr6”,
                                   CompanyPublicNotInterested: “BalanceSheetItr6”);

Now if you were to add any new entityType to the “SwitchSupported” function, you will get a compile time errors!

This is awesome. The use of generics lets you return functions — by using Func<> or Action<>

I like static typing as I don’t have a lot of QA resources — Ruby and Lispers will scorn at this. I don’t know, looks like a poor man’s solution enabled by C# 3.0.

By the way, I find TypeScript project very good. Cheerio. I hope this helps someone!

One Response to A fun note in C# on switching on enums

  1. Dheeraj Kumar July 27, 2013 at 6:22 am #

    You’re doing it wrong. This violates “Tell, don’t ask” principle.

    http://pragprog.com/articles/tell-dont-ask
    http://robots.thoughtbot.com/post/27572137956/tell-dont-ask