难以输入System.Linq.Enumerable.Select的参数

时间:2014-11-03 06:21:10

标签: c# linq

我一直盯着这一段时间而不确定如何修复它。

我要做的就是填写arptable description属性,它与设备表中的地址匹配。我不是想从arptable创建另一个集合。

错误:

  

无法从用法推断出方法'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable,System.Func)'的类型参数。尝试明确指定类型参数。

以下是有问题的代码:

 IEnumerable<ARPTABLE> GetARPTable()
    {
        IpTable arp = new IpTable();
        IEnumerable<ARPTABLE> arptable = arp.GetArpTable();


        arptable.ToList().ForEach(i =>
        {
            DeviceTable.Where(j => j.PhysicalAddress == i.MAC)
                       .Select(y =>
                           {
                               i.Description = y.Model ?? y.DeviceName;
                           });

        });

        return arptable;

    }

其中DeviceTable是

public ObservableCollection<Device> DeviceTable { get; set; }

感谢您提供任何帮助(或更好的方式)。

3 个答案:

答案 0 :(得分:3)

编译器遇到问题,因为你的lambda表达式没有正确写入,所以它在类型推断上失败了。不幸的是,这个方法的整个构造都被打破了,我不确定我是否真的理解你在这里要完成的任务。

但是在编译方面,你的方法应该更像这样:

IEnumerable<ARPTABLE> GetARPTable()
{
    IpTable arp = new IpTable();
    IEnumerable<ARPTABLE> arptable = arp.GetArpTable();

    foreach (var i in arptable)
    {
        Device j = DeviceTable.FirstOrDefault(j => j.PhysicalAddress == i.MAC);

        if (j != null)
        {
            i.Description = j.Model ?? j.DeviceName;
        }
    }

    return arptable;
}

作为一般说明:不要使用像Select()这样的方法来简单地访问集合中的每个元素。除非您评估返回的Select(),否则实际上不会评估您为IEnumerable<T>方法提供的表达式,在这种情况下您不会这样做。即使您评估IEnumerable<T>,也是对该方法的低效误用。

此外,虽然某些人可能认为List<T>.ForEach()很方便,但仅仅为了调用该方法,将IEnumerable<T>转换为List<T>是浪费的。定期的foreach语句工作正常,效率更高。

答案 1 :(得分:2)

LINQ不能用于填充数据。它是一种查询语言,因此Select方法返回一个新序列。用foreach做吧。我想它可能看起来像这样,虽然我不确定我的逻辑是否正确。

foreach(var table in arptable)
{
    var device = DeviceTable.SingleOrDefault(...);
    if (device != null)
    {
        table.Description = device.Model ?? device.DeviceName;
    }
}

至于你目前的表格

arptable.ToList().ForEach(i =>

这实际上没有必要,如果你不必要,为什么要将序列列入清单?只是用ForEach?我们可以做得更好。

DeviceTable.Where(j => j.PhysicalAddress == i.MAC)
           .Select(y => i.Description = y.Model ?? y.DeviceName);

这将返回一个新序列,您不存储在任何局部变量中。 LINQ查询不应该有副作用,它反对lambda演算,LINQ本身背后的想法。

答案 2 :(得分:1)

我喜欢其他答案。如果您仍想使用linq,您可以这样做:

IEnumerable<ARPTABLE> GetARPTable()
    {
        IpTable arp = new IpTable();
        IEnumerable<ARPTABLE> arptable = arp.GetArpTable();

        arptable = arptable.Select(i =>
        {
            Device device = DeviceTable.SingleOrDefault(j => j.PhysicalAddress == i.MAC);

            if (device != null)
            {
                i.Description = device.Model ?? device.DeviceName;
            }

            return i;
        });

        return arptable;

    }