当用 var 声明时,x 指的是类型的东西ILRetArray'1
;如果声明为ILArray<double>
,则为ILArray'1
。这些是公共基础 (ILDenseArray) 的兄弟子类。A 的类型是ILArray<double>
,它的数组索引运算符返回类型ILRetArray<ElementType>
。
在这两个类之间有两种方式的隐式转换运算符。
看起来当A[full, 0]
被分配给一个类型由类型推断决定的变量时,编译器使它成为 A 的数组索引运算符的返回类型:ILRetArray<ElementType>
。但是,如果您将 x 的类型显式声明为ILArray<double>
,则会调用隐式转换运算符并且您会得到一个不同的实际对象。
然后将它传递给norm
期望ILInArray
的 ,并调用另一个隐式转换运算符。那个有一个错误。它破坏了 ILRetArray 的内部状态。在调用之前尝试此行norm
:
var d = (ILInArray<double>)x;
...并且它对 x 的影响与调用相同norm
。所以就是这样的转换。
我还没有将源代码下载到 ILNumerics 以识别错误的详细信息。这可能是一个被禁止的操作,在这种情况下,我希望他们有更好的错误报告(更新见@HaymoKutschbach 的回答如下:事实上就是这种情况;ILRetArray
设计上是一个 volatile 类型,旨在有效直到第一个隐式转换运算符被调用)。
向 ILNumerics 提交错误报告并查看您收到的回复可能会很有趣(更新:这个线程中有一个来自 ILN 的人,所以没关系)。
但是在回答您的问题时:使用 var; 时确实需要谨慎一点;当有任何歧义的可能性时避免它。当涉及隐式转换运算符时,您需要特别小心。我已经忘记了那些甚至存在于 C# 中的东西。我不喜欢他们。当然,这个错误不是由他们使用隐式转换运算符引起的;这只是一个错误。但是操作员在不知不觉中极大地混淆了代码中发生了什么的问题。我更喜欢类型转换在源代码中可见。
感谢您发布此信息,这很有趣。