为什么我需要用这个简单的 LINQ 表达式来引用 System.Numerics?
Why am I required to reference System.Numerics with this simple LINQ expression?
首先,我知道如何到reference 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; }
}
它用在 class 中,需要 double[]
数组用作第三方依赖项的参数。我使用这个 LINQy lambda 链构造它们:
using Accord.Math;
// ...
double[] _wavelengths = points.Select(point => point.Wavelength).ToArray();
double[] _intensities = points.Select(point => point.Intensity).ToArray();
这是由那些 LINQ 表达式引起的错误:
Error CS0012
The type Complex
is defined in an assembly that is not referenced.
You must add a reference to assembly
System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
我知道这种错误可能是由引用外部程序集的未使用方法重载引起的,例如 here、,但 .Select()
和 .ToArray()
都没有引用 Complex
的重载。怎么回事?
编辑:
这完全复制了编译问题,如果删除 using Accord.Math;
,该问题就会消失:
using System.Linq;
using Accord.Math;
public class A
{
public A(IEnumerable<double> d)
{
double[] arr = d.ToArray();
}
}
(Here 是 Accord.Math
。)
您可以查看 Github 上的 Accord.Math 项目,因为它引用了 System.Numerics
。您很可能有一些代码使用引用 Complex
类型的 Accord.Math
类型,因此您需要引用 dll。
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Numerics" Condition="'$(Configuration)' != 'NET35'" />
<Reference Include="System.Xml" />
</ItemGroup>
我认为问题是由于 Accord.Math.ComplexMatrix
- 带有一堆扩展方法的静态 class,包括:
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();
}
}
首先,我知道如何到reference 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; }
}
它用在 class 中,需要 double[]
数组用作第三方依赖项的参数。我使用这个 LINQy lambda 链构造它们:
using Accord.Math;
// ...
double[] _wavelengths = points.Select(point => point.Wavelength).ToArray();
double[] _intensities = points.Select(point => point.Intensity).ToArray();
这是由那些 LINQ 表达式引起的错误:
Error CS0012
The typeComplex
is defined in an assembly that is not referenced.
You must add a reference to assembly
System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
我知道这种错误可能是由引用外部程序集的未使用方法重载引起的,例如 here、,但 .Select()
和 .ToArray()
都没有引用 Complex
的重载。怎么回事?
编辑:
这完全复制了编译问题,如果删除 using Accord.Math;
,该问题就会消失:
using System.Linq;
using Accord.Math;
public class A
{
public A(IEnumerable<double> d)
{
double[] arr = d.ToArray();
}
}
(Here 是 Accord.Math
。)
您可以查看 Github 上的 Accord.Math 项目,因为它引用了 System.Numerics
。您很可能有一些代码使用引用 Complex
类型的 Accord.Math
类型,因此您需要引用 dll。
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Numerics" Condition="'$(Configuration)' != 'NET35'" />
<Reference Include="System.Xml" />
</ItemGroup>
我认为问题是由于 Accord.Math.ComplexMatrix
- 带有一堆扩展方法的静态 class,包括:
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();
}
}