C# 为什么是<;enum>;无法强制转换为<;int?>;?
为什么C# 为什么是<;enum>;无法强制转换为<;int?>;?,c#,linq,casting,C#,Linq,Casting,为什么enum的集合无法强制转换为int? enum Test { A = 1, B = 2 }; int? x = (int?)Test.A; // Valid var collection1 = new[] { Test.A }.Cast<int>().ToList(); // InvalidCastException has thrown (Specified cast is not valid.) var collection2 = new[] { Test.A
enum
的集合无法强制转换为int?
enum Test { A = 1, B = 2 };
int? x = (int?)Test.A; // Valid
var collection1 = new[] { Test.A }.Cast<int>().ToList();
// InvalidCastException has thrown (Specified cast is not valid.)
var collection2 = new[] { Test.A }.Cast<int?>().ToList();
enum测试{A=1,B=2};
智力?x=(int?)Test.A;//有效的
var collection1=new[]{Test.A}.Cast().ToList();
//已引发InvalidCastException(指定的强制转换无效。)
var collection2=new[]{Test.A}.Cast().ToList();
Cast方法只能执行装箱/拆箱转换、引用转换以及枚举类型与其基础整数类型之间的转换。不过,取消装箱必须是正确的类型-它不能取消装箱到可为空的类型(与C#转换不同)
i、 e.无Cast
步骤。但是,如果您有一个对象
数组,则这不起作用:
// Fails
var collection1 = new object[] { Test.A }.Select(x => (int?) x)
.ToList();
无法将装箱的枚举值取消装箱为可为空的int值。不过,在这种情况下,
Cast
版本仍然可以工作,因为它将两个步骤分开(首先取消装箱到int
,然后从int
转换到int?
)我不知道为什么Cast()
不起作用,但您可以使用Select()
来做您想做的事情
var collection = new[] { Test.A }.Select(item => (int?)item).ToList();
这是因为内部
Cast()
执行以下操作:
object o = Test.A;
int i = (int)o; // This is valid.
int? ni = (int?)o; // This is not valid!
您必须首先将(Cast()转换为int:
var collection3 = new[] { Test.A }.Cast<int>().ToList().Cast<int?>().ToList();
这是行不通的,因为我们需要了解什么是enum,什么是int?(可为空int) int?不是真正的int,而是Nullable的一般实例,-语法T?是System.Nullable的缩写,其中T是值类型。这两种形式可以互换 Enum枚举元素的默认基础类型为int 因此,int和enum之间存在隐式转换。但是枚举(int)到null(这是完全不同的引用类型)之间的隐式转换并不存在。这就是为什么您会看到InvalidCastException异常
在第一个
int中的哪个位置?x=(int?)测试A代码>语句您正在强制显式转换,以装箱值类型并获取整数或获取空值,这是有效的,因为将枚举装箱到对象中,然后将其作为int?
解除装箱将返回一个int。。我不记得曾经以这种方式使用linq进行过铸造,我只使用已知类型:/
。。。我想{Test.A}.Select(x=>(int?.x)。ToList()
也应该可以工作?@Kobi:查看我的最新编辑-我已经浏览了几个版本:)也可以通过在Select:Select(x=>(int?)x
中强制转换两次值来避免Cast()
。但是,如果集合仅实现非泛型IEnumerable,则需要使用Cast()。这就是我3分钟前修复它的原因。@Jaroslav:你知道为什么Cast().Cast()
不起作用吗?@Homam:在内部,Cast()
在将对象强制转换为目标类型之前,会将值装箱到对象,而不能将装箱枚举直接强制转换为Nullable
类型。它在内部工作,就像Jaroslav所展示的那样。Test的Cast()
与(int?)(对象)测试相同。A
总是会失败。但有趣的是,Cast().Cast()
不起作用,因为Cast().Select(x=>x)。Cast()
工作正常。@mgronber:Cast()
如果枚举数的类型已经正确,则不会包装它Cast()
对枚举器实例没有影响。在本例中,它与IEnumerable的new[]{Test.A}相同<因此,code>arr.Cast().Cast
与arr.Cast()
相同,因为IEnumerator.MoveNext()
首先将值强制转换为对象
。
object o = Test.A;
int i = (int)o; // This is valid.
int? ni = (int?)o; // This is not valid!
var collection3 = new[] { Test.A }.Cast<int>().ToList().Cast<int?>().ToList();
var collection4 = new object[] { Test.A, null }.Select(i => i == null ? null : (int?)(int)i).ToList();