Generic Method – How to specify type constraint on T for enum type

In my current application I really need to write a generic method that accept any enum type as a parameter. Let me first explain my situation why I need generic method.  Here is the method that I need to convert into generic method.

Second parameter of the method is Enum type that has all the categories.
public enum LogCategory
{
Default,
UserInterface,
BusinessLogic,
DataAccess,
Security,
Errors
}
<div>

This LogCategory enum class is residing inside the class library project(let’s call it DataAccess).  I have another web application( let’s call it “Web1”) that calls that “Error” method to log the error but the situation is that web application has its own LogCategory class inside that.  So when I pass LogCategory enum of Web1 to Error method it gives me an error saying that “Cannot convert Web1.LogCategory into DataAccess.LogCategory” because both are different class residing in different project.  So I need to write a generic “Error” method that accepts any Enum type as a parameter.

That’s sounds interesting for me. Another time “Generic” made my life very easy.  Here is what I came up with.

public static void Error<T>(string msg, T logCat)
{
  //Here T is generic type.
  EntLib.Logger.Write(msg, logCat.ToString(), 3, 1000, TraceEventType.Error);
  //EntLib = Microsoft.Practices.EnterpriseLibrary.Logging;
}

But this method is very very generic I can pass any object type as T like Error<SomeXClass>(“message”,objOfSomeXClass).   I need to put the constraint on T so I can only pass Enum type.  I came accross where clause that is used to specify constraints on the types.

public static void Error<T>(string msg, T logCat)  : where T: Enum
{
//Here T is generic type.
EntLib.Logger.Write(msg, logCat.ToString(), 3, 1000, TraceEventType.Error);
//EntLib = Microsoft.Practices.EnterpriseLibrary.Logging;
}
<div><em>

hmm but that didn’t work for me.  It threw compiler error saying “Type Expected”.  So there is no easy way to specify enum type constraint.  Since Enum type implements IConvertible interface, here is what I can use.

public static void Error<T>(string msg, T logCat)  : where T: struct,IConvertible
{
//Here T is generic type.
EntLib.Logger.Write(msg, logCat.ToString(), 3, 1000, TraceEventType.Error);
//EntLib = Microsoft.Practices.EnterpriseLibrary.Logging;
}
<div><em>

That’s little bit restricated.  I tried calling Error<SomeXClass>(“message”,objOfSomeXClass), it threw me compiler error saying “The type ‘SomeXClass’ must be a non-nullable value type in order to use it as parameter ‘T’ in the generic type or method ‘Error<T>(string, T)'”.  That’s better.  But that will still allow to pass value type implementing IConvertible interface but that’s rare.  I can also check type of T and validate that if T is actually Enum type in code that will restric even more.  Here is the final version.

public static void Error<T>(string msg, T logCat)  where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
{
string errorMessage = string.Format("{0} must be an enumarted type", typeof(T).ToString());
throw new ArgumentException(errorMessage, typeof(T).ToString());
}
EntLib.Logger.Write(msg, logCat.ToString(), 3, 1000, TraceEventType.Error);
//EntLib = Microsoft.Practices.EnterpriseLibrary.Logging;
}

It’s friday and I am really happy having this generic method that resolves my issue.  Hope this helps you as well.

Posted in Microsoft Technology Tagged with:
2 comments on “Generic Method – How to specify type constraint on T for enum type
  1. AndyFletcherg says:

    Hey – I am really happy to find this. Good job!

  2. reuhIntetry says:

    Just looked the thread! Good thread!

Ads