문제

나는 현재 구현하는 수업을 만들려고 노력하고 있습니다 IEnumerable<T> 부모의 속성을 통해 서로를 참조하는 객체의 평평한 목록에서 계층 구조를 구성하기 위해. 나는 이것에 대한 유창한 인터페이스를 쓰고 싶다.

IEnumerable<Tab> tabs = GetTabs();

IEnumerable<TabNode> tabNodes = tabs.AsHierarchy().WithStartLevel(2).WithMaxDepth(5);

수율 진술에 대해 NodeHierarchy : IEnumerable<TabNode> 수업:

private IEnumerable<TabNode> _nodes;

public NodeHierarchy(IEnumerable<Tab> tabs)
{
    _nodes = CreateHierarchy(tabs);
}

public IEnumerable<TabNode> CreateHierarchy(IEnumerable<Tab> tabs)
{
    /* About this block: I'm trying to find the top level 
    nodes of the first tab collection, maybe this is done poorly? */
    var tabIds = tabs.Select(t => t.TabID);
    IEnumerable<TabNode> nodes = from tab in tabs
                             where !tabIds.Contains(tab.ParentId)
                                 select new TabNode {
                                            Tab = node,
                                            ChildNodes = CreateHierarchy(tabs, node.TabID, 1),
                                            Depth = 1 };
    return nodes;
}

아니면 다음과 같은 일을 해야하는지 여부는 다음과 같습니다.

private IEnumerable<TabNode> _nodes;

public NodeHierarchy(IEnumerable<Tab> tabs)
{
    _nodes = CreateHierarchy(tabs);
}

public IEnumerable<TabNode> CreateHierarchy(IEnumerable<Tab> tabs)
{
var tabIds = tabs.Select(t => t.TabID);
IEnumerable<Tab> startingNodes = from tab in tabs
                                 where !tabIds.Contains(tab.ParentId)
                                 select tab;

foreach(Tab node in startingNodes)
{
    yield return
    new TabNode()
        {
        Tab = node,
        ChildNodes = CreateHierarchy(tabs, node.TabID, 1),
        Depth = 1
    };
}
도움이 되었습니까?

해결책

아니, select new 평가를 트리거하지 않습니다. 이것은 다음에 대한 전화에 매핑됩니다.

 .Select(tab => new TabNode {...})

그리고 그것을 주목하십시오 Select (LINQ-to-Objects의 경우)는 본질적으로 다음과 같습니다.

public static IEnumerable<TDest> Select<TSource,TDest>(
    this IEnumerable<TSource> source,
    Func<TSource,TDest> selector)
{
    foreach(TSource item in source)
    {
        yield return selector(source);
    }
}

여기서 핵심 요점은 게으른 것을 평가한다는 것입니다. 한 번에 모두가 아닙니다.

어느 접근 방식도 비교할 수 있어야합니다. 유일한 차이점은 yield return, 약간 코드는 즉시 실행됩니다. 그러나 빌드 할 코드 만 .Where(...).Select(...) 체인 - 결과를 반복하기 시작할 때까지 실제로 행을 처리하지 않습니다.

또한, 데이터 소스에 따라 TSQL 생성기가 불필요한 열을 건너 뛸 수 있으므로 LINQ-to-SQL 백엔드와 같은 접근 방식이 실제로 더 효율적일 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top