Weitere ähnliche Inhalte Ähnlich wie C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~ (20) Mehr von Fujio Kojima (20) C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~2. •
•
• http://blog.shos.info
•
•
7. •
IEnumerable<int> sequence1 = new[] { 1, 1, 2, 3, 5, 8, 13, 21, 34 };
IEnumerable<int> sequence2 = sequence1.Where (x => x % 2 == 0);
IEnumerable<int> sequence3 = sequence2.Select (x => x * x );
foreach (int item in sequence3)
Console.WriteLine(item);
ソースコード
参照
9. •
ソースコード
参照
IEnumerable<int> sequence1 = new[] { 1, 1, 2, 3, 5, 8, 13, 21, 34 };
IEnumerable<int> sequence2 = sequence1.Where (x => x % 2 == 0);
IEnumerable<int> sequence3 = sequence2.Select (x => x * x );
foreach (int item in sequence3)
Console.WriteLine(item); 実際にsequence3 から値が取り出さ
れるまで、sequence1 から値は取り
出されず、Where やSelect に渡した
デリゲートも実行されない
11. •
var data = new EmployeeDataClassesDataContext();
data.Log = Console.Out;
var sequence1 = data.Employee;
var sequence2 = sequence1.Where (
ソースコード
参照
employee => employee.Name.Contains("田") );
var sequence3 = sequence2.Select (
employee => new { 番号= employee.Id, 名前= employee.Name });
foreach (var employee in sequence3)
Console.WriteLine("{0}: {1}", employee.番号, employee.名前);
12. •
SELECT [t0].[Id], [t0].[Name]
FROM [dbo].[Employee] AS [t0]
•
SELECT [t0].[Id] AS [番号], [t0].[Name] AS [名前]
FROM [dbo].[Employee] AS [t0]
WHERE [t0].[Name] LIKE @p0
-- @p0: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [%田%]
13. •
public static class Enumerable
{
public static class Queryable
{
public static IQueryable<T> Where<T>(this IQueryable<T> source,
Expression<Func<T, bool>> predicate);
}
public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
Func<T, int, bool> predicate);
}
•
15. •
class Program
{
static void Main()
{
ソースコード
Func<int, int, int> sequence1 = (x, y) => x + y;
Func<int, int, int> sequence2 = (x, y) => { return x + y; };
Expression<Func<int, int, int>> expression1 = (x, y) => x + y;
//Expression<Func<int, int, int>> expression2 = (x, y) =>
{ return x + y; };
}
}
ブロックが含まれるラムダ式は式として扱えない
(IQueryable<T> には使えない)
参照
16. •
•
var sequence4 = from employee in data.Employee
where employee.Name.Contains("田")
select new { 番号= employee.Id,
名前= employee.Name };
19. •
class Foo : IQueryable
{
public Type ElementType
{ get { throw new NotImplementedException(); } }
public Expression Expression
{ get { throw new NotImplementedException(); } }
public IQueryProvider Provider
{ get { throw new NotImplementedException(); } }
public IEnumerator GetEnumerator()
{ throw new NotImplementedException(); }
}
ソースコード
参照
21. •
ソースコード
参照
Expression<Func<int, int, int>> expression = (x, y) => x + y;
((Expression)expression).Show();
28. •
•
•
•
•
Assembly Module
Type
・Class
・Interface
・Value Type
FieldInfo
PropertyInfo
EventInfo
MethodInfo
ConstructorInfo ParameterInfo
35. •
•
•
CodeDOM CodeDOMProvider
ソースコード
(C#、VB、JScript)
アセンブリ
GenerateCodeFromNamespace
CompileAssemblyFromDom
38. •
•
•
• http://msdn.microsoft.com/ja-jp/library/f7dy01k1(v=vs.110).aspx
40. Expression<Func<Employee, bool>> expression = employee => employee.Name.Contains("山");
Parameters
Body Object
Method
Arguments
Expression
Member
employee =>
employee.Name.Con
tains("山")
employee.Name
Contains
employee
Name
“山”
employee
employee.Name.Co
ntains("山")
45. •
static Func<int, int, int> AddByExpression()
{
// 生成したい式
// (int x, int y) => x + y
// 引数x の式
var x = Expression.Parameter(type: typeof(int));
// 引数y の式
var y = Expression.Parameter(type: typeof(int));
// x + y の式
var add = Expression.Add (left: x, right: y);
// (x, y) => x + y の式
var lambda = Expression.Lambda (add, x, y );
// ラムダ式をコンパイルしてデリゲートとして返す
return (Func<int, int, int>)lambda.Compile();
}
ソースコード
参照
46. •
static Func<int, int, int> AddByExpression()
{
// 生成したい式
// (int x, int y) => x + y
// 引数x の式
var x = Expression.Parameter(type: typeof(int));
// 引数y の式
var y = Expression.Parameter(type: typeof(int));
// x + y の式
var add = Expression.Add (left: x, right: y);
// (x, y) => x + y の式
var lambda = Expression.Lambda (add, x, y );
// ラムダ式をコンパイルしてデリゲートとして返す
return (Func<int, int, int>)lambda.Compile();
}
ソースコード
参照
50. •
// Expression (式) によるメソッド呼び出しメソッドの生成
static Func<T, TResult> CallByExpression<T, TResult>(string methodName)
{
// 生成したい式の例:
// (T item) => item.methodName()
// 引数item の式
var parameterExpression = Expression.Parameter(type: typeof(T), name:
"item");
// item.methodName() の式
var callExpression = Expression.Call(
instance: parameterExpression,
method : typeof(T).GetMethod(methodName, Type.EmptyTypes)
);
// item => item.methodName() の式
var lambda = Expression.Lambda(callExpression, parameterExpression);
// ラムダ式をコンパイルしてデリゲートとして返す
return (Func<T, TResult>)lambda.Compile();
}
ソースコード
参照
53. •
1.
2.
1.
2.
3.
1.
2.
3.
4.
1.
2.
3.
58. •
•
•
•
• http://blog.jhashimoto.net/entry/20120616/1339806360
62. • ソースコード
pubic class QueryProvider : IQueryProvider
{
public IQueryable<TCollection>
CreateQuery<TCollection>(Expression expression)
{ return new QueryableData<TCollection>(this, expression); }
IQueryable IQueryProvider.CreateQuery(Expression expression)
{ return null; }
public TResult Execute<TResult>(Expression expression)
{ return default(TResult); }
public object Execute(Expression expression)
{
// ここで式木を解釈して、IEnumerable を作って返す
}
}
参照
64. •
static void Main()
{
IQueryable<int> query1 = new QueryableData<int>(new QueryProvider());
Console.WriteLine(query1.Expression);
IQueryable<int> query2 = query1.Where(x => x % 2 == 0);
Console.WriteLine(query2.Expression);
IQueryable<int> query3 = query2.OrderBy(x => x);
Console.WriteLine(query3.Expression);
IQueryable<int> query4 = query3.Select(x => x * x);
Console.WriteLine(query4.Expression);
foreach (int item in query4)
Console.WriteLine(item);
}
ソースコード
参照
67. •
public class MyExpressionVisitor : ExpressionVisitor
{
protected override Expression VisitBinary(BinaryExpression expression)
{ return base.VisitBinary(expression); }
protected override Expression VisitConstant(ConstantExpression expression)
{ return base.VisitConstant(expression); }
protected override Expression VisitMethodCall(MethodCallExpression expression)
{ return base.VisitMethodCall(expression); }
protected override Expression VisitParameter(ParameterExpression expression)
{ return base.VisitParameter(expression); }
…… 等々……
}
ソースコード
参照
68. •
☆式(x, y) => x + y
二項演算((x + y)) - 右辺: x, 左辺: y, 型: System.Int32
引数(x) - 名前: x, 型: System.Int32
引数(y) - 名前: y, 型: System.Int32
引数(x) - 名前: x, 型: System.Int32
引数(y) - 名前: y, 型: System.Int32
☆式text => text.Contains("福")
メソッドコール(text.Contains("福")) - メソッド名: Contains, 型: System.Boolean
引数(text) - 名前: text, 型: System.String
定数("福") - 値: 福, 型: System.String
引数(text) - 名前: text, 型: System.String
69. •
public class QueryableTimeline<TElement> : IOrderedQueryable<TElement>
{
public IQueryProvider Provider { get; private set; }
public Expression Expression { get; private set; }
public Type ElementType
{ get { return typeof(TElement); } }
public QueryableTimeline()
{
Provider = new TimelineQueryProvider();
Expression = Expression.Constant(this);
}
…… 途中省略……
}
ソースコード
参照