LINQ에서 "새로운 선택"이 평가 /로드를 트리거합니까?
-
03-07-2019 - |
문제
나는 현재 구현하는 수업을 만들려고 노력하고 있습니다 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 백엔드와 같은 접근 방식이 실제로 더 효율적일 수 있습니다.
제휴하지 않습니다 StackOverflow