铸造操作符纯粹是C#编译器级别的功能,运行时不知道任何关于它们的信息,所以没有简单的方法通过泛型Cast方法来实现此操作。要做到这一点的方法之一是执行运行时代码生成:
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);
}
}
但后来你会失去编译时检查:
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
另一种方式是在Puzzling Enumerable.Cast InvalidCastException但这种使用反射作为将不适用于从int到long的内置转换。
看看这是你的问题:http://stackoverflow.com/questions/445471/puzzling-enumerable-cast-invalidcastexception/445497#445497 – 2011-01-25 08:11:23