应用于通用枚举集合的Cast .Cast 会导致无效的强制转换exception

enum Gender { Male, Female } var k = new[] { Gender.Male }.Cast().ToList().Cast().ToList(); //alright var p = new[] { Gender.Male }.Cast().Cast().ToList(); //InvalidCastException 

第二种情况的原因是什么? 我知道我不能把一个盒装的enumint? 直接,但我做了两个阶段的转换,即Cast.Cast应该正常工作。

编辑:

考虑到以下工作,这是令人惊讶的:

 object o = Gender.Male; int i = (int)o; // so here the cast is not to an entirely different type, which works 

好的,我来找出原因,这仍然很奇怪。 我应该首先检查一下Cast实现!

这就是Cast的实现方式:

 public static IEnumerable Cast(this IEnumerable source) { IEnumerable enumerable = source as IEnumerable; if (enumerable != null) { return enumerable; // this is the culprit.. } if (source == null) { throw Error.ArgumentNull("source"); } return Enumerable.CastIterator(source); } private static IEnumerable CastIterator(IEnumerable source) { foreach (object current in source) { yield return (TResult)((object)current); } yield break; } 

现在的问题是第一个 Cast调用:

 new[] { Gender.Male }.Cast() 

这里的source as IEnumerable ,其中sourcenew[] { Gender.Male }TResultgenerics方法中的 int返回一个非null值(这基本上意味着( new[] { Gender.Male }是一个IEnumerable在generics上下文中,因此它返回相同的可枚举的后面是Gender[] ,并且在下一个Cast调用中,执行实际的Cast ,从Genderint?失败。至于为什么这样做发生在通用语境中, 在这个问题中抓住它 。

这是由于延期执行。 后一个语句实际上试图将Gender.Maleint? 。 相反,第一个语句实际上对int执行强制转换操作并在推迟执行之前获取List以将它们转换为int? ; 明确intint? 已经定义了隐含转换。