Linq对象枚举

时间:2011-01-11 06:09:00

标签: c# linq

我是linq的新手。我确信由于经验不足我缺少一些东西。

问题: 我使用linq查询对象并返回可枚举的Acct对象where o.Diff!=0

如果我尝试枚举结果,我会收到错误unable to cast object of type System.Collections.Generic.KeyValuePair '2[Acct]' to type 'Acct'

问题: 如何从Linq查询返回可枚举的Acct对象?

提前致谢!

public class AcctSum
{
  string ID;
  Decimal Amt1;
  Decimal Amt2;
  Decimal Diff;
  ArrayList<AcctDet> lines;
}

public class AcctInfo
{
  Dictionary<string,AcctSum> acct

  //code that adds the data...
  public iEnumerable Discrepancies()
  {
    var results = (from Acct a in acct
                   where a.Diff != 0
                   select a).AsEnumerable<Acct>();
    foreach (var result in results)//at runtime this generates an error

    {
    }                                    
    return results.GetEnumerator();
  }
}

5 个答案:

答案 0 :(得分:3)

问题在于,当您遍历字典时,您将每个项目都转换为Acct,而实际上,Dictionary中的每个项目都是KeyValuePair。尝试类似:

from KeyValuePair<string,AcctSum> acctKVP in acct // assuming acct is of type Dictionary<string,AcctSum>
where acctKvp.Value.Diff != 0

答案 1 :(得分:1)

当您遍历acct时,每个项目都是字典中的键/值对。假设Acct对象是每对中的值,您将获得所有非零帐户:

from a in acct.Values
where a.Diff != 0
select a

答案 2 :(得分:0)

嗯,这是b / c acct是一个字典(它是一个IEnumerable&lt; KeyValuePair&gt;,iirc,在引擎盖下。将你的来源从acct改为acct.Values

答案 3 :(得分:0)

首先,返回类型应该是IEnumerator,而不是IEnumerable。 其次,acct包含一组键值对,因此您必须对键值运行查询(在本例中)

void Main()
{
    var acctInfo = new AcctInfo();
    acctInfo.Discrepancies();

}
public class AcctSum
{

    string ID;
    Decimal Amt1;
    Decimal Amt2;
    public Decimal Diff;
    ArrayList lines;
}

public class AcctInfo
{
    public IEnumerator Discrepancies()
    {
        var acct = new Dictionary<int, AcctSum>
                       {{1, new AcctSum() {Diff = 0.0M}}, {2, new AcctSum() {Diff = 1.0M}}};

        var results = (from AcctSum a in acct.Values where a.Diff != 0 select a).AsEnumerable();

        foreach (var result in results)//at runtime this generates an error
        {

        }
        return results.GetEnumerator();
    }
}

答案 4 :(得分:0)

正如其他人所说,听起来你想要迭代价值而不是关键/价值对。

这意味着你可以使用这样的查询:

var results = from acctSum value in acct.Values
              where acctSum.Diff != 0
              select acctSum;

但我个人不打算在这种情况下使用查询表达式。我只是使用扩展方法:

var results = acct.Values.Where(acctSum => acctSum.Diff != 0);

现在,就返回类型而言,我强烈怀疑您想要返回IEnumerable<AcctSum>而不是IEnumeratorIEnumerator<T>。所以你可能想要:

public IEnumerable<AcctSum> Discrepancies()
{
    return acct.Values.Where(acctSum => acctSum.Diff != 0);
}

或者您可能希望“实现”查询 - 一次性获取所有结果,然后返回这些结果(而不是返回可以延迟迭代的查询)。例如:

public IEnumerable<AcctSum> Discrepancies()
{
    return acct.Values.Where(acctSum => acctSum.Diff != 0).ToList();
}

特别是,通过实现查询,您允许调用者在迭代这些结果时修改acct - 如果他们在迭代原始查询时尝试这样做,他们将会得到例外。

您还需要更改AcctSum类,因为ArrayList不是.NET中的通用类型。您的意思是使用List<T>吗?