vb.net 无法将源数组类型分配给枚举上的目标数组类型

vb.net Source array type cannot be assigned to destination array type on Enum

我不得不将 vb.net 项目从 .NetFramework 4 更新到 .NetFramework 4.7.2。在此过程中,以下代码现在抛出错误

Dim actuatorModelsArr = DirectCast(retNumberList, Array) Dim
Dim actuatorModels = actuatorModelsArr.Cast(Of ACTUATORMODELS)().ToList()

错误是System.ArrayTypeMismatchException: Source array type cannot be assigned to destination array type.

retNumberList 是一个整数数组 ACTUATORMODELS 是一个枚举

在.netFramework 4版本中actuatorModels是一个枚举列表 {System.Collections.Generic.List`1[FisherIECLib.ACTUATORMODELS]}

稍后在模块中通过 linq 使用该列表来获取枚举之一作为 return 值。

是否有解决此问题的方法或创建枚举列表的方法?

提前致谢, 汉克

我觉得它停止工作很有趣。您可以用 Select 替换代码并强制转换以使其工作

Dim retNumberList = {1, 2, 3, 4}
' either of these will produce a List of your Enum
Dim a = retNumberList.Select(Function(i) DirectCast(i, ACTUATORMODELS)).ToList()
Dim b = retNumberList.Select(Function(i) CType(i, ACTUATORMODELS)).ToList()

至于原来的不行:

Dim c = retNumberList.Cast(Of ACTUATORMODELS)().ToList()

文献表明这相当于 (type)obj c# 风格的转换,但是 vb.net 转换的两个版本都在 select 中工作。我不知道为什么。

djv 的回答有助于解决您的问题。希望这个答案能解释出了什么问题。如果您在未类型化的 IEnumerable 上查看 Cast(Of T) 的参考源,您会发现首先发生的是 C# 等效项:

Dim asTyped = TryCast(source, IEnumerable(Of TResult))
If asTyped IsNot Nothing Then Return asTyped

令人惊讶的是,此转换适用于 Integer()IEnumerable(Of ACTUATORMODELS)。这引发了问题,因为当涉及到从结果序列中生成 List(Of T) 时,事实证明 Integer()ACTUATORMODELS() 实际上是不可互换的,但是 Cast 已经将序列视为它们。

根据一些测试,此问题似乎是由于此极端情况与 List(Of T) 范围构造函数如何工作的极端情况以及 Integer() 的更一般极端情况的相互作用而引起的对比 TEnum().

在遍历 Integer() 就好像它是 IEnumerable(Of TEnum) 的一般情况下,它是有效的。您可以在序列上创建一个 For Each 循环,枚举变量将具有 TEnum 作为类型,并且您将看到这些值就好像它们是 TEnum.

问题出在 List(Of T) 的范围构造函数中,以及针对实现 ICollection(Of T) 的源的优化。在这种情况下,ctor 将尝试使用 ICollection(Of T).CopyTo 将项目复制到列表的内部存储中。这是错误最终发生的地方,因为(回到Cast(Of T)的实现)源仍然是Integer()数组,而Array.Copy(通过Array.CopyTo)不是可以尝试使用 TEnum().

的目的地来做到这一点

我觉得这是某个地方的错误,尽管我不确定它是在 Cast(Of T)、List(Of T) 范围构造函数中还是在数组复制处理中。我也不确定它是否会得到修复,因为它是一个极端情况,看起来像是重要的优化,需要非常专业的检查才能捕捉到。