Casting operators are purely C# compiler level features, the run-time doesn't know anything about them so there is no simple way to implement this via generic Cast method. One way to do this is to perform run-time code generation:
public static class Converter<TSource, TResult>
{
static Converter()
{
var sourceParameter = Expression.Parameter(typeof(TSource));
var conversionExpression = Expression.Lambda<Func<TSource, TResult>>(
Expression.Convert(sourceParameter, typeof(TResult)),
sourceParameter);
Instance = conversionExpression.Compile();
}
public static Func<TSource, TResult> Instance
{
get;
private set;
}
}
public static class EnumerableEx
{
public static IEnumerable<TResult> Cast<TSource, TResult>(this IEnumerable<TSource> source)
{
return source.Select(Converter<TSource, TResult>.Instance);
}
}
but then you'll loose compile-time checking:
var test = new[] { new Foo() };
var ok = test.Cast<Foo, int>().ToList(); // compiles and works ok
var error = test.Cast<Foo, double>().ToList(); // compiles but fails at run-time
Another way is to use reflection as in Puzzling Enumerable.Cast InvalidCastException but this will not work with built-in conversions like from int to long.