Generic Methods as Casts
Somebody just asked me which of the following API design alternatives is better. They both do what we could call “casting.”
// Generic Method “Cast”
var foo = someInstance.SomeMethod<IFoo>();
// Simple Cast
var foo = (IFoo)someInstance.SomeMethod();
The Generic method approach can potentially have two benefits. A constraint can tell users what the subset of valid casts is. For example, the following API will allow casts to a collection (a subtype of IEnumerable):
public TCollection SomeMethod<TCollection>() where TCollection:IEnumerable {
…
}
If the user calls this method and tries to “cast” the return value to let’s say an Int32, the compiler with complain. For example,
var int someInstance.SomeMethod<int>();
… will generate the following error:
The type 'int' must be convertible to 'System.Collections.IEnumerable' in order to use it as parameter 'TCollection' in the generic type or method 'SomeClass.SomeMethod<TCollection>()'
Secondly, the Generic method might do different things based on the type parameter. The method relying on a simple cast has now knowledge about the type the user will cast it’s return value to.
public TCollection SomeMethod< TCollection >()
where TCollection:IEnumerable,new() {
TCollection newCollection = new TCollection ();
ArrayList newArray = newCollection as ArrayList;
if (newArray != null) newArray.Capacity = 0;
return newCollection;
}
If neither of these benefits applies in your case, I would use a simple cast. It’s more transparent in terms of what’s going on. The users of a generic method might wonder what kind of “magic” is being done with the generic type parameter.