...
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace Unit { class T { public void Test() { Console.WriteLine("Test Class!"); } } class S { private List<int> ids = new List<int>(); public string Name { set; get; } public List<int> Ids { set { ids = value; } get { return ids; } } } class ET { public void Run() { //add Add(4, 5);//+ AddAssign(4, 5); Subtract(5, 4);//- SubtractAssign(5,4); Multiply(4,5); MultiplyAssign(4,5); Divide(4, 2); DivideAssign(4,2); Decrement(3);//i--; Increment(3);//++ Modulo(); And(true, false); //& AndAlso(true, false); //&& Or(true, false); OrElse(true, false); //|| LessThan(4, 5); Coalesce(1, 2); Coalesce(null, 2); Is(); If(); IfElse(); Condition(); Switch(5); Loop(9); TypeAs(); Convert(); New(); NewArray(); NewArrayBounds(); ListInit(); ListBind(); } /// <summary> /// + /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void Add(int a,int b) { var left = Expression.Parameter(typeof(int)); var right = Expression.Parameter(typeof(int)); Expression exp = Expression.Add(left, right); Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } public static int Add2(int a,int b) { return 100; } /// <summary> /// 利用方法+ /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void AddAssign(int a, int b) { var left = Expression.Parameter(typeof(int)); var right = Expression.Parameter(typeof(int)); Expression exp = Expression.AddAssign(left, right, this.GetType().GetMethod("Add2")); Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } /// <summary> /// & /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void And(bool a, bool b) { var left = Expression.Parameter(typeof(bool)); var right = Expression.Parameter(typeof(bool)); Expression exp = Expression.And(left, right); Expression<Func<bool, bool, bool>> lambda = Expression.Lambda<Func<bool, bool, bool>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } /// <summary> /// && /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void AndAlso(bool a, bool b) { var left = Expression.Parameter(typeof(bool)); var right = Expression.Parameter(typeof(bool)); Expression exp = Expression.AndAlso(left, right); Expression<Func<bool, bool, bool>> lambda = Expression.Lambda<Func<bool, bool, bool>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } /// <summary> /// | /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void Or(bool a, bool b) { var left = Expression.Parameter(typeof(bool)); var right = Expression.Parameter(typeof(bool)); Expression exp = Expression.Or(left, right); Expression<Func<bool, bool, bool>> lambda = Expression.Lambda<Func<bool, bool, bool>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } /// <summary> /// || /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void OrElse(bool a, bool b) { var left = Expression.Parameter(typeof(bool)); var right = Expression.Parameter(typeof(bool)); Expression exp = Expression.OrElse(left, right); Expression<Func<bool, bool, bool>> lambda = Expression.Lambda<Func<bool, bool, bool>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } /// <summary> /// - /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void Subtract(int a, int b) { var left = Expression.Parameter(typeof(int)); var right = Expression.Parameter(typeof(int)); Expression exp = Expression.Subtract(left, right); Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } private void SubtractAssign(int a, int b) { var left = Expression.Parameter(typeof(int)); var right = Expression.Parameter(typeof(int)); Expression exp = Expression.SubtractAssign(left, right, this.GetType().GetMethod("Add2")); Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } /// <summary> /// * /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void Multiply(int a, int b) { var left = Expression.Parameter(typeof(int)); var right = Expression.Parameter(typeof(int)); Expression exp = Expression.Multiply(left, right); Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } private void MultiplyAssign(int a, int b) { var left = Expression.Parameter(typeof(int)); var right = Expression.Parameter(typeof(int)); Expression exp = Expression.MultiplyAssign(left, right, this.GetType().GetMethod("Add2")); Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } /// <summary> /// / /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void Divide(int a, int b) { var left = Expression.Parameter(typeof(int)); var right = Expression.Parameter(typeof(int)); Expression exp = Expression.Divide(left, right); Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } /// <summary> /// a/=b /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void DivideAssign(int a, int b) { var left = Expression.Parameter(typeof(int)); var right = Expression.Parameter(typeof(int)); Expression exp = Expression.DivideAssign(left, right, this.GetType().GetMethod("Add2")); Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } /// <summary> /// -- /// </summary> /// <param name="a"></param> private void Decrement(int a) { var left = Expression.Parameter(typeof(int)); Expression exp = Expression.Decrement(left); Expression<Func<int, int>> lambda = Expression.Lambda<Func<int, int>>(exp, new ParameterExpression[] { left }); var l = lambda.Compile(); var r = l(a); Console.WriteLine(r); } /// <summary> /// ++ /// </summary> /// <param name="a"></param> private void Increment(int a) { var left = Expression.Parameter(typeof(int)); Expression exp = Expression.Increment(left); Expression<Func<int, int>> lambda = Expression.Lambda<Func<int, int>>(exp, new ParameterExpression[] { left }); var l = lambda.Compile(); var r = l(a); Console.WriteLine(r); } /// <summary> /// > /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void LessThan(int a, int b) { var left = Expression.Parameter(typeof(int)); var right = Expression.Parameter(typeof(int)); Expression exp = Expression.LessThan(left, right); Expression<Func<int, int, bool>> lambda = Expression.Lambda<Func<int, int, bool>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a,b); Console.WriteLine(r); } /// <summary> /// ?? /// </summary> /// <param name="a"></param> /// <param name="b"></param> private void Coalesce(int? a, int b) { var left = Expression.Parameter(typeof(int?)); var right = Expression.Parameter(typeof(int)); var right2 = Expression.Assign(right, Expression.Default(typeof(int))); Expression exp = Expression.Coalesce(left, right2); Expression<Func<int?, int, int>> lambda = Expression.Lambda<Func<int?, int, int>>(exp, new ParameterExpression[] { left, right }); var l = lambda.Compile(); var r = l(a, b); Console.WriteLine(r); } public static bool IsFalse(bool flag){ return false; } /// <summary> /// is /// </summary> private void Is() { var v1 = Expression.Parameter(typeof(bool)); var v11 = Expression.Assign(v1,Expression.Constant(true)); var v2 = Expression.IsFalse(v1, this.GetType().GetMethod("IsFalse")); Expression exp = Expression.IsFalse(v2); var v3=Expression.TypeIs(Expression.Constant(new List<int>()),typeof(IList<int>)); Expression<Func<bool,bool>> lambda = Expression.Lambda<Func<bool,bool>>(exp, new ParameterExpression[] {v1 }); var l = lambda.Compile(); var r = l(true); Console.WriteLine(r); Expression<Func<bool>> lambda2 = Expression.Lambda<Func<bool>>(v3); var l2 = lambda2.Compile(); Console.WriteLine(l2()); } /// <summary> /// if /// </summary> private void If() { var v1 = Expression.Variable(typeof(int),"a"); var v11 = Expression.Assign(v1, Expression.Constant(10)); var v2 = Expression.GreaterThan(v11, Expression.Constant(9)); Expression exp = Expression.IfThen(v2,Expression.Call(typeof(Console).GetMethod("WriteLine",new Type[]{typeof(int)}),v1)); Expression exp2 = Expression.Block(new[]{v1},exp); Expression<Action> lambda = Expression.Lambda<Action>(exp2, new ParameterExpression[] { }); var l = lambda.Compile(); l(); } /// <summary> /// if else /// </summary> private void IfElse() { var v1 = Expression.Variable(typeof(int), "a"); var v11 = Expression.Assign(v1, Expression.Constant(10)); var v2 = Expression.GreaterThan(v11, Expression.Constant(9)); Expression exp = Expression.IfThenElse(v2, Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }), Expression.Constant("True")), Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }), Expression.Constant("False"))); Expression exp2 = Expression.Block(new[] { v1 }, exp); Expression<Action> lambda = Expression.Lambda<Action>(exp2, new ParameterExpression[] { }); var l = lambda.Compile(); l(); } /// <summary> /// trueTest?ifTrue:ifFalse; /// </summary> private void Condition() { var v1 = Expression.Variable(typeof(int), "a"); var v11 = Expression.Assign(v1, Expression.Constant(10)); var v2 = Expression.GreaterThan(v1, Expression.Constant(9)); Expression exp = Expression.Condition(v2, Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }), Expression.Constant("True")), Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }), Expression.Constant("False"))); Expression exp2 = Expression.Block(new[] { v1 },v11, exp); Expression<Action> lambda = Expression.Lambda<Action>(exp2, new ParameterExpression[] { }); var l = lambda.Compile(); l(); } /// <summary> /// switch /// </summary> /// <param name="i"></param> private void Switch(int i) { var par = Expression.Parameter(typeof(int)); var target = Expression.Label(typeof(int),"a"); var exp = Expression.Switch(par, Expression.Break(target, Expression.Constant(-5)), Expression.SwitchCase(Expression.Break(target, par), Expression.Constant(1))); var lbl = Expression.Label(target, Expression.Constant(0)); var block = Expression.Block(exp,lbl); Expression<Func<int, int>> lambda = Expression.Lambda<Func<int, int>>(block, new ParameterExpression[] { par }); var l = lambda.Compile(); Console.WriteLine(l(i)); } /// <summary> /// while(true){} /// </summary> /// <param name="i"></param> private void Loop(int i) { var par = Expression.Parameter(typeof(int)); var ret = Expression.Variable(typeof(int), "ret"); var v11 = Expression.Assign(ret, Expression.Constant(0)); var lbl = Expression.Label(typeof(int)); var lbl2 = Expression.Label(lbl,Expression.Constant(0)); var block1 = Expression.Block(Expression.AddAssign(ret,par),Expression.SubtractAssign(par,Expression.Constant(2))); var condition = Expression.IfThenElse(Expression.GreaterThan(par, Expression.Constant(0)),block1, Expression.Break(lbl, ret)); var block2 = Expression.Block(new[] { ret }, v11, Expression.Loop(condition), lbl2);// Expression.Block(new[] { ret }, v11, Expression.Loop(condition,lbl)) 可以達到一樣的效果 Expression<Func<int, int>> lambda = Expression.Lambda<Func<int, int>>(block2, new ParameterExpression[] { par }); var l = lambda.Compile(); Console.WriteLine(l(i)); } /// <summary> /// as /// </summary> private void TypeAs() { Expression s = Expression.Constant(1); var t=Expression.TypeAs(s, typeof(object)); var call = Expression.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }), Expression.Unbox(t, typeof(int))); Expression<Action> lambda = Expression.Lambda<Action>(call); var l=lambda.Compile(); l(); } /// <summary> /// 強轉 class定義TypeConverter,TypeConverterAttribute /// </summary> private void Convert() { Expression s = Expression.Constant(7.5); var t = Expression.Convert(s, typeof(int)); var call = Expression.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }),t); Expression<Action> lambda = Expression.Lambda<Action>(call); var l = lambda.Compile(); l(); } /// <summary> /// % /// </summary> private void Modulo() { Expression s1 = Expression.Constant(7); Expression s2 = Expression.Constant(4); var t = Expression.Modulo(s1,s2); Expression<Func<int>> lambda = Expression.Lambda<Func<int>>(t); var l = lambda.Compile(); Console.WriteLine(l()); } /// <summary> /// new /// </summary> private void New() { Expression s = Expression.Constant(7); var t = Expression.New(typeof(T)); var call = Expression.Call(t, typeof(T).GetMethod("Test")); Expression<Action> lambda = Expression.Lambda<Action>(call); var l = lambda.Compile(); l(); } /// <summary> /// 初始化數組對象new int[]{7} /// </summary> private void NewArray() { Expression s = Expression.Constant(7); var t = Expression.NewArrayInit(typeof(int),s); var call = Expression.Call(t, typeof(int[]).GetProperty("Length").GetGetMethod()); Expression<Func<int>> lambda = Expression.Lambda<Func<int>>(call); var l = lambda.Compile(); Console.WriteLine(l()); } /// <summary> /// new int[7] /// </summary> private void NewArrayBounds() { Expression s = Expression.Constant(7); var t = Expression.NewArrayBounds(typeof(int), s); var call = Expression.Call(t, typeof(int[]).GetProperty("Length").GetGetMethod()); Expression<Func<int>> lambda = Expression.Lambda<Func<int>>(call); var l = lambda.Compile(); Console.WriteLine(l()); } /// <summary> /// new List<int>(){5} /// </summary> private void ListInit() { Expression s = Expression.Constant(5); var lst = Expression.New(typeof(List<int>)); var t = Expression.ListInit(lst,s); var call = Expression.Call(t, typeof(List<int>).GetProperty("Count").GetGetMethod()); Expression<Func<int>> lambda = Expression.Lambda<Func<int>>(call); var l = lambda.Compile(); Console.WriteLine(l()); } /// <summary> /// var s=new S();s.Ids.Add(5);s.Ids.Add(7); /// </summary> private void ListBind() { Type s = typeof(S); var n=Expression.New(s); var ids=s.GetProperty("Ids"); var l=typeof(List<int>); var n2 = Expression.New(l); var e1 = Expression.ElementInit(l.GetMethod("Add"), Expression.Constant(5)); var e2 = Expression.ElementInit(l.GetMethod("Add"