为什么我需要参考系统.用这个简单的LINQ表达式计算数字

本文关键字:简单 LINQ 表达式 数字 计算 参考 系统 为什么 | 更新日期: 2023-09-27 18:10:59

首先,我知道如何引用System.Numerics以使编译器访问它所要求的Complex类型,我只是不明白为什么有必要。

我有这样一个基本结构体:

/// <summary>
///     Describes a single point on a spectrum.
/// </summary>
public struct SpectrumPoint
{
    public SpectrumPoint(double wavelength, double intensity)
    {
        Wavelength = wavelength;
        Intensity = intensity;
    }
    public double Intensity { get; }
    public double Wavelength { get; }
}

在需要double[]数组作为第三方依赖参数的类中使用。我使用这个LINQy lambda链来构造它们:

using Accord.Math;
// ...
double[] _wavelengths = points.Select(point => point.Wavelength).ToArray();
double[] _intensities = points.Select(point => point.Intensity).ToArray();

这是由LINQ表达式引起的错误:

错误CS0012
类型Complex在未引用的程序集中定义。
必须添加对程序集
的引用System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

我知道这种错误可能是由引用外部程序集的未使用的方法重载引起的,就像这里的,但是.Select().ToArray()都没有引用Complex的任何重载。这是怎么呢


编辑:

这完全复制了编译问题,如果删除using Accord.Math;,这个问题就会消失:

using System.Linq;
using Accord.Math;
public class A
{
    public A(IEnumerable<double> d)
    {
        double[] arr = d.ToArray();
    }
}

(这里是Accord.Math)

为什么我需要参考系统.用这个简单的LINQ表达式计算数字

我认为问题是由于Accord.Math.ComplexMatrix -一个静态类与一堆扩展方法,包括:

public static double[,] ToArray(this Complex[] c);

我得到错误:

using static Accor.Math.ComplexMatrix;

…但我没有得到它与类似的using static指令在同一名称空间的其他类型。

ToArray调用显式地更改为Enumerable.ToArray调用,这样可以使错误消失:

_wavelengths = Enumerable.ToArray(points.Select(point => point.Wavelength));
_intensities = Enumerable.ToArray(points.Select(point => point.Intensity));

…这进一步表明是ComplexMatrix.ToArray造成了问题。

基本上你不想使用任何导入的扩展方法。选择:

  • 直接调用Enumerable.ToArray,如上所示
  • 删除using Accord.Math并完全限定该命名空间内类型的任何使用
  • 使用名称空间别名,例如using AM = Accord.Math,然后将其用于名称空间内类型的任何使用,例如var p3 = new AM::Point3()
  • 在命名空间中使用任何类型的类型别名,例如using Point3 = Accord.Math.Point3;,然后你可以正常使用var p3 = new Point3();

现在不可否认的是,编译器可以潜在地计算出该调用是不可行的,无论Complex是如何定义的,因为不可能有单个用户定义的从double[]Complex[]的转换,但是发现这将增加语言和编译器的复杂性。

这里有一个真的简短但完整的例子来演示它:

using System.Linq;
using Accord.Math; // Comment this out and the error goes away
class Test
{
    static void Main(string[] args)
    {
        args.ToArray();
    }
}    

你可以看看雅阁。数学项目在Github上看到它引用了System.Numerics。你很可能有一些代码使用Accord.Math类型来引用Complex类型,所以你需要引用dll。

<ItemGroup> 
  <Reference Include="System" /> 
  <Reference Include="System.Data" /> 
  <Reference Include="System.Numerics" Condition="'$(Configuration)' != 'NET35'" /> 
  <Reference Include="System.Xml" /> 
</ItemGroup>