为什么我需要使用这个简单的LINQ表达式引用System.Numerics?

kdb*_*man 12 .net c# linq

首先,我知道如何参考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; }
}
Run Code Online (Sandbox Code Playgroud)

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

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

这是由那些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();
    }
}
Run Code Online (Sandbox Code Playgroud)

(Accord.Math.)

Jon*_*eet 11

我相信问题是由于Accord.Math.ComplexMatrix- 一个带有一堆扩展方法的静态类,包括:

public static double[,] ToArray(this Complex[] c);
Run Code Online (Sandbox Code Playgroud)

我收到错误:

using static Accor.Math.ComplexMatrix;
Run Code Online (Sandbox Code Playgroud)

...但是using static对于同一名称空间中的其他类型,我没有得到类似的指令.

将您的ToArray调用更改为显式Enumerable.ToArray调用会使错误消失:

_wavelengths = Enumerable.ToArray(points.Select(point => point.Wavelength));
_intensities = Enumerable.ToArray(points.Select(point => point.Intensity));
Run Code Online (Sandbox Code Playgroud)

......这是进一步暗示它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();
    }
}    
Run Code Online (Sandbox Code Playgroud)