list.Where(x => x > 0) みたいなのから from x in list where x > 0 select x を復元

タイトルどおり、式木からクエリ式を復元するようなプログラムを書いてみた。

http://ufcpp.net/study/csharp/source/ExpressionTree.zip
QueryExpression.cs が件の処理をしてる部分。

以下のようなコードで、

var q0 = Make.Expression((IEnumerable<int> five) =>
	from baker in five
	from cooper in five
	from fletcher in five
	from miller in five
	from smith in five
	where Distinct(baker, cooper, fletcher, miller, smith)
	where baker != 5
	where cooper != 1
	where fletcher != 1 && fletcher != 5
	where miller > cooper
	where Discrete(smith, fletcher)
	where Discrete(fletcher, cooper)
	select new { baker, cooper, fletcher, miller, smith }
	);

var q = new QueryExpression(q0);

foreach (var l in q.Queries)
{
	Console.Write("{0}\n", l);
}

以下のような出力を得ます。

from baker in five
from cooper in five
from fletcher in five
from miller in five
from smith in five
where Distinct(new [] {baker, cooper, fletcher, miller, smith})
where (baker != 5)
where (cooper != 1)
where ((fletcher != 1) && (fletcher != 5))
where (miller > cooper)
where Discrete(smith, fletcher)
where Discrete(fletcher, cooper)
select new <>f__AnonymousType5`5(baker, cooper, fletcher, miller, smith)

匿名型を使った member init のところに <>f__AnonymousType5 ってのが出てる以外は元と一致。

これを使えば、クエリ式を機械的に最適化(where を極力上に持ってきたり、foreach, if, yield retrun に置き換えたり)できるはず。

.Cast とか .GroupBy とか、対応した方がよさそうだけど未対応のものもいくらかあり。