Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

C# Generics with primary datatypes

0.00/5 (No votes)
6 Feb 2013 1  
C# Generics with primary datatypes.

Recently me and my friend discussed about Generics in C# and after a long discussion we agreed on one common definition, which is as below: 

Generics is a feature which is useful when you have a set of types going to perform some set of functions which are the same but the output differs from one type to another type.

Alternatively, we can say "whatever the type is, I want to be able to do some common set of operation(s)." The implementations of the operation are different, but the idea is the same. To understand this properly I created a console application in which I created a method which does addition as below.

public T Add<T>(T t1, T t2)
{
    T t3 = t1 + t2;
    return t3;
}

So as per the generic definition, this should work but when I complied, I got the following compile time error:

Error 1 Operator '+' cannot be applied to operands of type 'T'.

First when I encountered the error I thought that it might be that I did something wrong. After sometime I realised that whatever you passed as a generic type it is converted to an object. So if I pass any primary data type it first gets boxed automatically and than the generic function take care of that. By following this fact if we apply +,- etc. kind of arithmetic operations on a primary data type, the generic function is not going to work because it gets converted to object, i.e., it is boxed.

To resolve the problem with the primary data types in generic functions I modified my above function as below.

public T Add<T>(T val1, T val2)
{
    if (val1 == null)
        throw new ArgumentNullException("val1");
    if (val2 == null)
        throw new ArgumentNullException("val2");

    object n1 = val1,
           n2 = val2;

    if (val1 is byte)
        return (T)((object)((byte)n1 + (byte)n2));
    if (val1 is short)
        return (T)((object)((short)n1 + (short)n2));
    if (val1 is int)
        return (T)((object)((int)n1 + (int)n2));
    if (val1 is long)
        return (T)((object)((long)n1 + (long)n2));
    if (val1 is float)
        return (T)((object)((int)n1 + (int)n2));
    if (val1 is double)
        return (T)((object)((double)n1 + (double)n2));

    throw new InvalidOperationException("Type " + typeof(T).ToString() + " is not supported.");

}

As you can see, in the above code, first I check the type of the object and if the type of the object matches then I perform the function that does the add operation. Basically I am unboxing the parameter passed to the function.

Conclusion

In generics, primary data types are treated as boxed objects so when you are coding generics for primary data types beware that you need to convert the passed parameter in the primary data type, i.e., you need to unbox the values again.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here