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

时间:2015-09-03 16:08:17

标签: c# .net linq

首先,我知道如何reference System.Numerics让编译器访问它所要求的Complex类型,我只是不明白为什么它是必要的。< / p>

我有这个基本结构:

/// <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

我知道这种错误可能是由引用外部程序集的未使用的方法重载引起的,例如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();
    }
}

HereAccord.Math。)

2 个答案:

答案 0 :(得分:11)

我认为问题是由于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[]的单一用户定义转换。 1}}到using System.Linq; using Accord.Math; // Comment this out and the error goes away class Test { static void Main(string[] args) { args.ToArray(); } } ,但发现这会增加语言和编译器的复杂性。

这是一个真正的简短但完整的示例,用于演示它:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
 $(document).ready(function(){
    $("#num").keyup(function(){
    $('.dynamicInput .row').remove();
    $('.dynamicInput h4').remove();
    if ($(this).val() > 0) {
        $('.dynamicInput').append('<h4>Please fill in the name and email of each extra attendees</h4>');
        var num = $(this).val();
        for (var i = 0; i < num; i++) {
            $('.dynamicInput').append('<div class="row"><div class="col1"><input type="text" name="attendeesName' + i + '" placeholder="Name" required /></div><div class="col2"><input type="text" name="attendeesEmail' + i + '" placeholder="Email" required /></div></div>');
        }
    }
    });
});
</script>
</head>
<body>
    <input type="number" id="num" min="0" max="20" required/>
    <div class="dynamicInput"></div>
</body> 
</html>

答案 1 :(得分:3)

您可以查看Github上的Accord.Math项目,因为它引用了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>