“ Select New” linqで評価/負荷をトリガーしますか?
-
03-07-2019 - |
質問
現在、ParentIdプロパティを介して相互に参照しているオブジェクトのフラットリストから階層を構築するために、 IEnumerable< T>
を実装するクラスを作成しようとしています。私はこのために流fluentなインターフェイスを書きたいので、このようなことをすることができます
IEnumerable<Tab> tabs = GetTabs();
IEnumerable<TabNode> tabNodes = tabs.AsHierarchy().WithStartLevel(2).WithMaxDepth(5);
それで、yieldステートメントについて、 NodeHierarchy:IEnumerable&lt; TabNode&gt;
クラス内で次のようなことができるかどうか疑問に思います:
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
がなければ、一部のコードがすぐに実行されることですが、をビルドするコードのみです。 (...)。Select(...)
チェーン-結果の反復を開始するまで、実際には行を処理しません。
さらに、データソースによっては、TSQLジェネレーターが不要な列をスキップできるため、その方法は実際にはより効率的です(たとえば、LINQ-to-SQLバックエンドの場合)。
所属していません StackOverflow