0

我有一个类和一组 IEnumerables,它们正在使用这个类来给我一个列表中的列表。(有关详细信息,请参阅此问题的答案。)

这是代码:

public IEnumerable<IEnumerable<WorkItemColumn>> EnumerateResultSet(WorkItemCollection queryResults)//DisplayFieldList displayFieldList)
{
    foreach (WorkItem workItem in queryResults)
    {
        yield return EnumerateColumns(queryResults.DisplayFields, workItem);   
    }
}

public IEnumerable<WorkItemColumn> EnumerateColumns(DisplayFieldList resultSet, WorkItem workItem)
{
    foreach (FieldDefinition column in resultSet)
        yield return new WorkItemColumn { Name = column.Name, Value = workItem[column.Name], WorkItemForColumn = workItem};
}

和班级:

public class WorkItemColumn
{
    public string Name { get; set; }
    public object Value { get; set; }
    public WorkItem WorkItemForColumn { get; set; }
}

我将此结果设置为我的 ListBox 的 ItemsSource

Form.QueryResultListSource = EnumerateResultSet(queryResults);

当我尝试捕获此列表框的事件时,问题就出现了:

public void QueryResultsSelectionChanged(SelectionChangedEventArgs e)
{
                                                   +-----------------+
                                                   v                 | 
    foreach (WorkItemColumn workItemColumn in e.AddedItems)          |
    {                                                                |
        AddWorkItemToPad(workItemColumn.WorkItemForColumn);          |
    }                                                +---------------|
                                                     |               |
                                                     v               |    
    foreach (WorkItemColumn workItemColumn in e.RemovedItems)        |
    {                                                                |
        RemoveWorkItemFromPad(workItemColumn.WorkItemForColumn);     |
    }                                                                |
                                                                     |    
}                                                                    |
                                                                     |
These items are where the problem is --------------------------------+

当我在调试时检查 e.AddedItems[0] 并且它说它的类型是 EnumerateColumns。

当我尝试转换为该类型时,Visual Studio 说(可以理解) EnumerateColumns 是一种方法,但用作类型。

那么,我怎样才能按类型引用它,以便我可以执行一个 foreach 循环并获取其中的内容呢?


这是我根据答案更新的代码:

public void QueryResultsSelectionChanged(SelectionChangedEventArgs e)
{
    foreach (IEnumerable<WorkItemColumn> workItemColumns in e.AddedItems)
    {
        if (workItemColumns.Count() > 0)
            AddWorkItemToPad(workItemColumns.First().WorkItemForColumn);                
    }

    foreach (IEnumerable<WorkItemColumn> workItemColumns in e.RemovedItems)
    {
        if (workItemColumns.Count() > 0)
            RemoveWorkItemFromPad(workItemColumns.First().WorkItemForColumn);    
    }
}
4

4 回答 4

2

问题是您的第一个方法没有产生第一个给出的每个结果 - 它产生了可枚举本身。编译器为迭代器生成的类型 - 但重要的是,它实现 IEnumerable<WorkItemColumn>了.

如果需要,您可以将每个项目投射到IEnumerable<WorkItemColumn>- 但目前还不清楚您要在QueryResultsSelectionChanged. 你可能想做:

foreach (IEnumerable<WorkItemColumn> workItemColumns in e.AddedItems)
{                                                   
    foreach(WorkItemColumn workItemColumn in workItemColumns)
    {
        AddWorkItemToPad(workItemColumn.WorkItemForColumn); 
    }
}

等等......或者你可能不会。在不知道自己真正想要做什么的情况下说出来是很棘手的。无论如何,关键在于您当前正试图将一系列项目视为单个项目。不要那样做:)

于 2009-12-28T23:41:05.597 回答
1

e.AddedItems[0]是编译器生成的隐藏迭代器类型的实例,不能直接使用。
但是,它实现了IEnumerable<WorkItemColumn>,因此您可以通过该接口使用它。

换句话说:

foreach (IEnumerable<WorkItemColumn> colSet in e.RemovedItems)        
    foreah(WorkItemColumn workItemColumn in colSet)
        RemoveWorkItemFromPad(workItemColumn.WorkItemForColumn);     
于 2009-12-28T23:41:32.613 回答
1

尽管使用迭代器可能不是解决此问题的最佳方法,但您可以通过将枚举存储在数组中来避免遇到的问题,如下所示:

using System.Linq;
...
Form.QueryResultListSource = EnumerateResultSet(queryResults).ToArray();

并将您的 EnumerateResultSet 更改为:

public IEnumerable<WorkItemColumn[]> EnumerateResultSet(WorkItemCollection queryResults)//DisplayFieldList displayFieldList) 
{ 
    foreach (WorkItem workItem in queryResults) 
    { 
        yield return EnumerateColumns(queryResults.DisplayFields, workItem).ToArray();    
    } 
} 

正如其他人所指出的,使用 yield 关键字您实际上是在返回一个知道如何迭代您希望枚举的项目的函数。但是为这个可枚举设置一个数据源并不是简单地执行一次并存储结果。使用迭代器可能会遇到很多性能问题,因为无论何时需要使用结果,都需要重新执行迭代。

于 2009-12-28T23:50:46.230 回答
0

为了完整起见,您确实应该包含 和 的相关AddedItems代码RemovedItems

尽管如此,以完全限定的形式(意味着包括命名空间)使用类型名称强制转换对象。这将使其绑定到类型而不是方法签名,因为该方法在类型级别不可用,但子类型将可用。

于 2009-12-28T23:45:50.907 回答