enum Gender { Male, Female }
var k = new[] { Gender.Male }.Cast<int>().ToList().Cast<int?>().ToList(); //alright
var p = new[] { Gender.Male }.Cast<int>().Cast<int?>().ToList(); //InvalidCastException
第二种情况的原因是什么?我知道我不能直接将enum
装箱int?
给Cast<int>.Cast<int?>
,但我会进行两阶段演员,即object o = Gender.Male;
int i = (int)o; // so here the cast is not to an entirely different type, which works
应该有效。
修改
考虑到以下情况,这是令人惊讶的:
{{1}}
答案 0 :(得分:4)
好的,我已经找到了原因,这仍然很奇怪。我应该首先自己检查Cast<T>
实施!
这就是Cast<T>
的实施方式:
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)
{
IEnumerable<TResult> enumerable = source as IEnumerable<TResult>;
if (enumerable != null)
{
return enumerable; // this is the culprit..
}
if (source == null)
{
throw Error.ArgumentNull("source");
}
return Enumerable.CastIterator<TResult>(source);
}
private static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source)
{
foreach (object current in source)
{
yield return (TResult)((object)current);
}
yield break;
}
现在问题出在第一次 Cast<int>
来电:
new[] { Gender.Male }.Cast<int>()
此处source as IEnumerable<TResult>
其中source
为new[] { Gender.Male }
而TResult
为int
在泛型方法中返回非空值(这基本上意味着(new[] { Gender.Male }
在通用上下文中是IEnumerable<int>
,因此它返回相同的可枚举回Gender[]
,并在下一个Cast<int?>
调用中,实际执行强制转换,从Gender
到int?
失败。至于为什么在通用上下文中发生这种情况,catch it in this question。
答案 1 :(得分:1)
这是由于延期执行。后一个语句实际上会尝试将Gender.Male
转换为int?
。相反,第一个语句实际上对int
执行强制转换操作,并在推迟执行以将其转换为List<int>
之前得到int?
;显然int
到int?
已经定义了隐含转换。