应用于通用枚举集合的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
第二种情况的原因是什么? 我知道我不能把一个盒装的enum
为int?
直接,但我做了两个阶段的转换,即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
,其中source
是new[] { Gender.Male }
而TResult
是generics方法中的 int
返回一个非null值(这基本上意味着( new[] { Gender.Male }
是一个IEnumerable
在generics上下文中,因此它返回相同的可枚举的后面是Gender[]
,并且在下一个Cast
调用中,执行实际的Cast
,从Gender
到int?
失败。至于为什么这样做发生在通用语境中, 在这个问题中抓住它 。
这是由于延期执行。 后一个语句实际上试图将Gender.Male
为int?
。 相反,第一个语句实际上对int
执行强制转换操作并在推迟执行之前获取List
以将它们转换为int?
; 明确int
到int?
已经定义了隐含转换。