C# Partial Specialization With Extension Methods
One of the things C# generics lacks (compared to C++ templates) is specialization (neither explicit nor partial). This can be very useful in some cases where you want to perform something differently for a specific T in a Class<T>.
With C# 3.0, there is a relatively easy way to achieve this, albeit not optimal, for reasons I'll specify later on. Take a look at the following piece of code:
public class SomeClass<T>
{
private readonly List<T> items = new List<T>();
internal void AddInternal(T item)
{
items.Add(item);
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public static class SomeClassExtensions
{
public static void Add<T>(this SomeClass<T> c, T item)
{
c.AddInternal(item);
}
public static void Add(this SomeClass<int> c, int item)
{
if (item <= 0)
{
throw new ArgumentOutOfRangeException("item", "Value must be a positive integer.");
}
c.AddInternal(item);
}
}
Instead of placing the Add method in SomeClass<T>, we put it in a static class that has extension methods. This allows the compiler to select the appropriate method according to the type parameter. (Side note: I've specified the EditorBrowsable attribute so that the class with the extensions would not appear in VS intellisense.)
The biggest caveat about this is that extension methods do no have access to private members, so the only option is to make the members internal, which, in many cases, leads to a bad design. If only extension method classes could be written as inner classes…
Also, extension methods, being static, could not be virtualized. You can, however, make the internal method "protected internal virtual".
4 Responses to C# Partial Specialization With Extension Methods
Tags
.NET 4 Animation Async Axum Blog C# ClearType Cloud CLR CodeValue Contests Deep Zoom Experiments Generics Google Ink Lectures Modeling Personal Pivot Prism Programming Languages Prolog Reflector RTL Sela Silverlight The Arbel Network Themes Threading Tips Visual Studio WCF Windows 7 Windows 2003 Windows Azure Windows Forms Windows Phone Windows Vista Windows XP WPF XAML ZuneArchives
- June 2011
- November 2010
- August 2010
- July 2010
- June 2010
- March 2010
- December 2009
- November 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- November 2007
- September 2007
- June 2007
- May 2007
- February 2007
- November 2006
- October 2006
- February 2006
- August 2005
- February 2005
- August 2004
- July 2004
- June 2004
- May 2004






Hi aelij,
Nice hack! Will come in handy.
But it works only partially.
E.g. when you try it with the following program:
static void main()
{
var c = new SomeClass<float>();
c.Add((float)-1);
c.Add((int)-1);
}
the generic Add method is always called (the int is silently converted to a float?), so no specialization takes place as in C++.
Hi Peter,
It’s not supposed to work. The specialization is for an instance of SomeClass<T>, not for each call to the Add() method. So, if you create a SomeClass<int>, the compiler will select the most specialized method.
Aelij.
Hi aelij,
Nice solution, but I think there is an issue if you try to use it from another generic function. For instance the code below will not call the overload:
void foo<T>(T t)
{
SomeClass<T> o = new SomeClass<T>();
0.Add(t);
}
static void main()
{
foo<int>(3); // calls SomeClassExtensions<T> instead of override
}
I think a better approach is the following:
class SomeType
{
}
class Foo<T>
{
public static Foo<T> CreateInstance()
{
if (typeof(T) == typeof(SomeType)) return new FooSomeType() as Foo<T>;
return new Foo<T>();
}
protected Foo()
{ }
public virtual void SomeMethod()
{
// what ever
}
private class FooSomeType : Foo<SomeType>
{
public override void SomeMethod()
{
// SomeType specific handling goed here
}
}
}
good one