目录
表达式目录树表达式目录树:语法树,或者说是一种数据结构
1.表达式目录树expression:system.linq.expressions;
2.描述了多个变量或者和常量之间的关系,按照一定的规则进行组装! - 可以向委托一样使用lambd表达式快捷声明;
- 不能有语句体,声明只能有一行代码;
- 可以通过compile(),编译成一个委托;
[size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
| [size=1em][size=1em]func<int, int, int> func = (m, n) =>
[size=1em]{
[size=1em] int i = 0;
[size=1em] return m * n + 2;
[size=1em]}; //委托 拉姆达表达式其实是作为委托的一个参数,本质是一个方法(匿名方法)
[size=1em]expression<func<int, int, int>> exp = (m, n) => m * n + 2; //数据结构--就像对一个计算做了一个精确的描述,展开之后发现,分为左边,右边,每个元素都可以把值都获取出来,二叉树
[size=1em]var erpplu= exp.compile();//表达式目录树可以通过compile 转换成一个委托
[size=1em]//表达式目录树:语法树,或者说是一种数据结构
[size=1em]int iresult1 = func.invoke(12, 23);
[size=1em]int iresult2 = exp.compile().invoke(12, 23);
|
表达式目录树的拼装手动拼装表达式目录树,不是用的lambda的快捷方式 [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
| [size=1em][size=1em]//表达式目录树的拼装
[size=1em]expression<func<int>> expression = () => 123 + 234; //两个常量相加-----表达式目录树的快捷声明
[size=1em]expression constant123 = expression.constant(123);
[size=1em]expression constant234 = expression.constant(234);
[size=1em]expression expressionadd = expression.add(constant123, constant234);
[size=1em]var exp = expression.lambda<func<int>>(expressionadd);
[size=1em]var func = exp.compile();
[size=1em]int iresult = func.invoke();
|
[size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
| [size=1em][size=1em]expression<func<int, int, int>> exp = (m, n) => m * n + m + n + 2; //快捷声明--其实编译器提供的便捷功能---语法糖--具体实现可通过反编译工具查看
[size=1em]//具体实现可通过反编译工具查看
[size=1em]parameterexpression parameterexpression = expression.parameter(typeof(int), "m");
[size=1em]parameterexpression parameterexpression2 = expression.parameter(typeof(int), "n");
[size=1em]expression expcontant2 = expression.constant(2, typeof(int));
[size=1em]expression multipley = expression.multiply(parameterexpression, parameterexpression2);
[size=1em]expression expadd = expression.add(multipley, parameterexpression);
[size=1em]expression expadd1 = expression.add(expadd, parameterexpression2);
[size=1em]expression expadd2 = expression.add(expadd1, expcontant2);
[size=1em]expression<func<int, int, int>> expression = expression.lambda<func<int, int, int>>(expadd2, new parameterexpression[]
[size=1em]{
[size=1em]parameterexpression,
[size=1em]parameterexpression2
[size=1em]});
[size=1em]func<int, int, int> fun = expression.compile();
[size=1em]int iresult = fun.invoke(10, 11);
|
[size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
[size=1em]20
[size=1em]21
[size=1em]22
[size=1em]23
[size=1em]24
[size=1em]25
[size=1em]26
[size=1em]27
[size=1em]28
| [size=1em][size=1em]var peoplequery = new list<people>().asqueryable();
[size=1em]expression<func<people, bool>> lambda = x => x.id.tostring().equals("5");
[size=1em]peoplequery.where(lambda);
[size=1em]parameterexpression parameterexpression = expression.parameter(typeof(people), "x");
[size=1em]fieldinfo idfield = typeof(people).getfield("id");
[size=1em]var idexp = expression.field(parameterexpression, idfield);
[size=1em]methodinfo tostring = typeof(int).getmethod("tostring", new type[0]);
[size=1em]var tostringexp = expression.call(idexp, tostring, array.empty<expression>());
[size=1em]var equals = typeof(string).getmethod("equals", new type[] { typeof(string) });
[size=1em]expression expressionconstant5 = expression.constant("5", typeof(string));
[size=1em]var equalsexp = expression.call(tostringexp, equals, new expression[]
[size=1em] {
[size=1em] expressionconstant5
[size=1em] });
[size=1em]expression<func<people, bool>> expression = expression.lambda<func<people, bool>>(equalsexp, new parameterexpression[]
[size=1em]{
[size=1em] parameterexpression
[size=1em]});
[size=1em]func<people, bool> func = expression.compile();
[size=1em]var bresult = func.invoke(new people()
[size=1em]{
[size=1em] id = 5,
[size=1em] name = "海贝"
[size=1em]});
[size=1em]new list<people>().asqueryable().where(expression);
|
应用
linq to sql[size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
| [size=1em][size=1em]var dbset = new list<people>().asqueryable();//ef dbset
[size=1em]dbset.where(p => p.age == 25 & p.name.contains("阳光下的微笑"));
[size=1em]expression<func<people, bool>> exp = null;
[size=1em]console.writeline("用户输入个名称,为空就跳过");
[size=1em]string name = console.readline();
[size=1em]if (!string.isnullorwhitespace(name))
[size=1em]{
[size=1em] exp = p => p.name.contains(name);
[size=1em]}
[size=1em]console.writeline("用户输入个最小年纪,为空就跳过");
[size=1em]string age = console.readline();
[size=1em]if (!string.isnullorwhitespace(age) && int.tryparse(age, out int iage))
[size=1em]{
[size=1em] exp = p => p.age > iage;
[size=1em]}
|
上面的玩法是不是只有最后一个条件才生效?如果需要多个条件都满足;怎么办? 当然是拼装啊;
拼装可以从最小粒度来组装表达式目录树;如果有一个封装,你把各种条件给我,我从最小粒度开始一个一个的拼装起来,不就是一个长的表达式目录树了吗? 解决方案:
调用方可以组装一个很长的表达式目录树传递过来;
表达式目录树传递过来以后,在这里应该做什么?应该解析;
所有信息都在表达式目录树里面,自然也可以把他解析(找出来)
解析就可以通过expressionvisitor解析----生成对应的sql语句;
expressionvisitor表达式目录树的访问者----访问者模式;
1.visit方法–访问表达式目录树的入口—分辨是什么类型的表达式目录
2.调度到更加专业的方法中进一步访问,访问一遍之后,生成一个新的表达式目录 —有点像递归,不全是递归;
3.因为表达式目录树是个二叉树,expressionvisitor一直往下访问,一直到叶节点;那就访问了所有的节点;
4.在访问的任何一个环节,都可以拿到对应当前环节的内容(参数名称、参数值。。),就可以进一步扩展; 为什么要使用表达式目录树来拼装解析呢:
1.可以提高重用性;
2.如果封装好一个方法,接受一个表达式目录树,在解析的时候,其实就是不断的访问,访问有规则;
3.任何一个表达式目录树都可以调用当前方法来解析;
4.表达式目录树可以支持泛型; [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
[size=1em]20
[size=1em]21
[size=1em]22
[size=1em]23
[size=1em]24
[size=1em]25
[size=1em]26
[size=1em]27
[size=1em]28
[size=1em]29
[size=1em]30
[size=1em]31
[size=1em]32
[size=1em]33
[size=1em]34
| [size=1em][size=1em]{
[size=1em] expression<func<people, bool>> lambda = x => x.age > 5 && x.id > 5
[size=1em] && x.name.startswith("1") // like '1%'
[size=1em] && x.name.endswith("1") // like '%1'
[size=1em] && x.name.contains("1");// like '%1%'
[size=1em] //string sql = string.format("delete from [{0}] where [age]>5 and [id] >5"
[size=1em] , typeof(people).name
[size=1em] , " [age]>5 and [id] >5" );
[size=1em] conditionbuildervisitor vistor = new conditionbuildervisitor();
[size=1em] vistor.visit(lambda);
[size=1em] console.writeline(vistor.condition());
[size=1em]}
[size=1em]{
[size=1em] // ((( [age] > '5') and( [name] = [name] )) or( [id] > '5' ))
[size=1em] string name = "aaa";
[size=1em] expression<func<people, bool>> lambda = x => x.age > 5 && x.name == name || x.id > 5;
[size=1em] conditionbuildervisitor vistor = new conditionbuildervisitor();
[size=1em] vistor.visit(lambda);
[size=1em] console.writeline(vistor.condition());
[size=1em]}
[size=1em]{
[size=1em] expression<func<people, bool>> lambda = x => x.age > 5 || (x.name == "a" && x.id > 5);
[size=1em] conditionbuildervisitor vistor = new conditionbuildervisitor();
[size=1em] vistor.visit(lambda);
[size=1em] console.writeline(vistor.condition());
[size=1em]}
[size=1em]{
[size=1em] expression<func<people, bool>> lambda = x => (x.age > 5 || x.name == "a") && x.id > 5;
[size=1em] conditionbuildervisitor vistor = new conditionbuildervisitor();
[size=1em] vistor.visit(lambda);
[size=1em] console.writeline(vistor.condition());
[size=1em]}
|
自己封装的解析器,这就是ef6的底层原理,根据表达式树自动生成相应的sql语句。 [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
[size=1em]20
[size=1em]21
[size=1em]22
[size=1em]23
[size=1em]24
[size=1em]25
[size=1em]26
[size=1em]27
[size=1em]28
[size=1em]29
[size=1em]30
[size=1em]31
[size=1em]32
[size=1em]33
[size=1em]34
[size=1em]35
[size=1em]36
[size=1em]37
[size=1em]38
[size=1em]39
[size=1em]40
[size=1em]41
[size=1em]42
[size=1em]43
[size=1em]44
[size=1em]45
[size=1em]46
[size=1em]47
[size=1em]48
[size=1em]49
[size=1em]50
[size=1em]51
[size=1em]52
[size=1em]53
[size=1em]54
[size=1em]55
[size=1em]56
[size=1em]57
[size=1em]58
[size=1em]59
[size=1em]60
[size=1em]61
[size=1em]62
[size=1em]63
[size=1em]64
[size=1em]65
[size=1em]66
[size=1em]67
[size=1em]68
[size=1em]69
[size=1em]70
[size=1em]71
[size=1em]72
[size=1em]73
[size=1em]74
[size=1em]75
[size=1em]76
[size=1em]77
[size=1em]78
[size=1em]79
[size=1em]80
[size=1em]81
[size=1em]82
[size=1em]83
[size=1em]84
[size=1em]85
[size=1em]86
[size=1em]87
[size=1em]88
[size=1em]89
[size=1em]90
[size=1em]91
[size=1em]92
[size=1em]93
[size=1em]94
[size=1em]95
[size=1em]96
[size=1em]97
[size=1em]98
[size=1em]99
[size=1em]100
[size=1em]101
[size=1em]102
[size=1em]103
[size=1em]104
[size=1em]105
[size=1em]106
[size=1em]107
[size=1em]108
[size=1em]109
[size=1em]110
[size=1em]111
[size=1em]112
[size=1em]113
| [size=1em][size=1em]public class conditionbuildervisitor : expressionvisitor
[size=1em]{
[size=1em] private stack<string> _stringstack = new stack<string>();
[size=1em] public string condition()
[size=1em] {
[size=1em] string condition = string.concat(this._stringstack.toarray());
[size=1em] this._stringstack.clear();
[size=1em] return condition;
[size=1em] }
[size=1em] /// <summary>
[size=1em] /// 如果是二元表达式
[size=1em] /// </summary>
[size=1em] /// <param name="node"></param>
[size=1em] /// <returns></returns>
[size=1em] protected override expression visitbinary(binaryexpression node)
[size=1em] {
[size=1em] if (node == null) throw new argumentnullexception("binaryexpression");
[size=1em] this._stringstack.push(")");
[size=1em] base.visit(node.right);//解析右边
[size=1em] this._stringstack.push(" " + node.nodetype.tosqloperator() + " ");
[size=1em] base.visit(node.left);//解析左边
[size=1em] this._stringstack.push("(");
[size=1em] return node;
[size=1em] }
[size=1em] /// <summary>
[size=1em] /// 解析属性
[size=1em] /// </summary>
[size=1em] /// <param name="node"></param>
[size=1em] /// <returns></returns>
[size=1em] protected override expression visitmember(memberexpression node)
[size=1em] {
[size=1em] if (node == null) throw new argumentnullexception("memberexpression");
[size=1em] //this._stringstack.push(" [" + node.member.name + "] ");
[size=1em] return node;
[size=1em] if (node.expression is constantexpression)
[size=1em] {
[size=1em] var value1 = this.invokevalue(node);
[size=1em] var value2 = this.reflectionvalue(node);
[size=1em] //this.conditionstack.push($"'{value1}'");
[size=1em] this._stringstack.push("'" + value2 + "'");
[size=1em] }
[size=1em] else
[size=1em] {
[size=1em] this._stringstack.push(" [" + node.member.name + "] ");
[size=1em] }
[size=1em] return node;
[size=1em] }
[size=1em] private object invokevalue(memberexpression member)
[size=1em] {
[size=1em] var objexp = expression.convert(member, typeof(object));//struct需要
[size=1em] return expression.lambda<func<object>>(objexp).compile().invoke();
[size=1em] }
[size=1em] private object reflectionvalue(memberexpression member)
[size=1em] {
[size=1em] var obj = (member.expression as constantexpression).value;
[size=1em] return (member.member as fieldinfo).getvalue(obj);
[size=1em] }
[size=1em] /// <summary>
[size=1em] /// 常量表达式
[size=1em] /// </summary>
[size=1em] /// <param name="node"></param>
[size=1em] /// <returns></returns>
[size=1em] protected override expression visitconstant(constantexpression node)
[size=1em] {
[size=1em] if (node == null) throw new argumentnullexception("constantexpression");
[size=1em] this._stringstack.push(" '" + node.value + "' ");
[size=1em] return node;
[size=1em] }
[size=1em] /// <summary>
[size=1em] /// 方法表达式
[size=1em] /// </summary>
[size=1em] /// <param name="m"></param>
[size=1em] /// <returns></returns>
[size=1em] protected override expression visitmethodcall(methodcallexpression m)
[size=1em] {
[size=1em] if (m == null) throw new argumentnullexception("methodcallexpression");
[size=1em] string format;
[size=1em] switch (m.method.name)
[size=1em] {
[size=1em] case "startswith":
[size=1em] format = "({0} like {1}+'%')";
[size=1em] break;
[size=1em] case "contains":
[size=1em] format = "({0} like '%'+{1}+'%')";
[size=1em] break;
[size=1em] case "endswith":
[size=1em] format = "({0} like '%'+{1})";
[size=1em] break;
[size=1em] default:
[size=1em] throw new notsupportedexception(m.nodetype + " is not supported!");
[size=1em] }
[size=1em] this.visit(m.object);
[size=1em] this.visit(m.arguments[0]);
[size=1em] string right = this._stringstack.pop();
[size=1em] string left = this._stringstack.pop();
[size=1em] this._stringstack.push(string.format(format, left, right));
[size=1em] return m;
[size=1em] }
[size=1em]}
|
[size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
[size=1em]20
[size=1em]21
[size=1em]22
[size=1em]23
[size=1em]24
[size=1em]25
[size=1em]26
[size=1em]27
[size=1em]28
[size=1em]29
[size=1em]30
[size=1em]31
[size=1em]32
| [size=1em][size=1em]internal static class sqloperator
[size=1em]{
[size=1em] internal static string tosqloperator(this expressiontype type)
[size=1em] {
[size=1em] switch (type)
[size=1em] {
[size=1em] case (expressiontype.andalso):
[size=1em] case (expressiontype.and):
[size=1em] return "and";
[size=1em] case (expressiontype.orelse):
[size=1em] case (expressiontype.or):
[size=1em] return "or";
[size=1em] case (expressiontype.not):
[size=1em] return "not";
[size=1em] case (expressiontype.notequal):
[size=1em] return "<>";
[size=1em] case expressiontype.greaterthan:
[size=1em] return ">";
[size=1em] case expressiontype.greaterthanorequal:
[size=1em] return ">=";
[size=1em] case expressiontype.lessthan:
[size=1em] return "<";
[size=1em] case expressiontype.lessthanorequal:
[size=1em] return "<=";
[size=1em] case (expressiontype.equal):
[size=1em] return "=";
[size=1em] default:
[size=1em] throw new exception("不支持该方法");
[size=1em] }
[size=1em] }
[size=1em]}
|
表达式目录扩展表达式目录树动态拼接的实现方式: [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
[size=1em]20
[size=1em]21
[size=1em]22
[size=1em]23
[size=1em]24
[size=1em]25
[size=1em]26
[size=1em]27
[size=1em]28
[size=1em]29
[size=1em]30
[size=1em]31
[size=1em]32
[size=1em]33
[size=1em]34
[size=1em]35
[size=1em]36
[size=1em]37
[size=1em]38
[size=1em]39
[size=1em]40
[size=1em]41
[size=1em]42
[size=1em]43
[size=1em]44
[size=1em]45
[size=1em]46
[size=1em]47
[size=1em]48
[size=1em]49
[size=1em]50
| [size=1em][size=1em]/// <summary>
[size=1em]/// 合并表达式 and or not扩展
[size=1em]/// </summary>
[size=1em]public static class expressionextend
[size=1em]{
[size=1em] /// <summary>
[size=1em] /// 合并表达式 expr1 and expr2
[size=1em] /// </summary>
[size=1em] /// <typeparam name="t"></typeparam>
[size=1em] /// <param name="expr1"></param>
[size=1em] /// <param name="expr2"></param>
[size=1em] /// <returns></returns>
[size=1em] public static expression<func<t, bool>> and<t>(this expression<func<t, bool>> expr1, expression<func<t, bool>> expr2)
[size=1em] {
[size=1em] //return expression.lambda<func<t, bool>>(expression.andalso(expr1.body, expr2.body), expr1.parameters); 错误的写法,两个表达式不是同一个参数
[size=1em] //将两个表达式的参数统一为参数c
[size=1em] parameterexpression newparameter = expression.parameter(typeof(t), "c");
[size=1em] newexpressionvisitor visitor = new newexpressionvisitor(newparameter);
[size=1em] var left = visitor.replace(expr1.body);
[size=1em] var right = visitor.replace(expr2.body); //为了能够生成一个新的表达式目录树
[size=1em] var body = expression.and(left, right);
[size=1em] return expression.lambda<func<t, bool>>(body, newparameter);
[size=1em] }
[size=1em] /// <summary>
[size=1em] /// 合并表达式 expr1 or expr2
[size=1em] /// </summary>
[size=1em] /// <typeparam name="t"></typeparam>
[size=1em] /// <param name="expr1"></param>
[size=1em] /// <param name="expr2"></param>
[size=1em] /// <returns></returns>
[size=1em] public static expression<func<t, bool>> or<t>(this expression<func<t, bool>> expr1, expression<func<t, bool>> expr2)
[size=1em] {
[size=1em] parameterexpression newparameter = expression.parameter(typeof(t), "c");
[size=1em] newexpressionvisitor visitor = new newexpressionvisitor(newparameter);
[size=1em] var left = visitor.replace(expr1.body);
[size=1em] var right = visitor.replace(expr2.body);
[size=1em] var body = expression.or(left, right);
[size=1em] return expression.lambda<func<t, bool>>(body, newparameter);
[size=1em] }
[size=1em] public static expression<func<t, bool>> not<t>(this expression<func<t, bool>> expr)
[size=1em] {
[size=1em] var candidateexpr = expr.parameters[0];
[size=1em] var body = expression.not(expr.body);
[size=1em] return expression.lambda<func<t, bool>>(body, candidateexpr);
[size=1em] }
[size=1em]}
|
[size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
| [size=1em][size=1em]/// <summary>
[size=1em]/// 建立新表达式
[size=1em]/// </summary>
[size=1em]internal class newexpressionvisitor : expressionvisitor
[size=1em]{
[size=1em] public parameterexpression _newparameter { get; private set; }
[size=1em] public newexpressionvisitor(parameterexpression param)
[size=1em] {
[size=1em] this._newparameter = param;
[size=1em] }
[size=1em] public expression replace(expression exp)
[size=1em] {
[size=1em] return this.visit(exp);
[size=1em] }
[size=1em] protected override expression visitparameter(parameterexpression node)
[size=1em] {
[size=1em] return this._newparameter;
[size=1em] }
[size=1em]}
|
调用方如下: [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
[size=1em]20
[size=1em]21
[size=1em]22
[size=1em]23
[size=1em]24
[size=1em]25
| [size=1em][size=1em] {
[size=1em] expression<func<people, bool>> lambda1 = x => x.age > 5;
[size=1em] expression<func<people, bool>> lambda2 = x => x.id > 5;
[size=1em] //expression<func<people, bool>> newexpress = x => x.age > 5 && x.id > 5;
[size=1em] expression<func<people, bool>> lambda3 = lambda1.and(lambda2); //且
[size=1em] expression<func<people, bool>> lambda4 = lambda1.or(lambda2);//或
[size=1em] expression<func<people, bool>> lambda5 = lambda1.not();//非
[size=1em] do1(lambda3);
[size=1em] do1(lambda4);
[size=1em] do1(lambda5);
[size=1em] }
[size=1em]private static void do1(expression<func<people, bool>> func)
[size=1em]{
[size=1em] list<people> people = new list<people>()
[size=1em] {
[size=1em] new people(){id=4,name="123",age=4},
[size=1em] new people(){id=5,name="234",age=5},
[size=1em] new people(){id=6,name="345",age=6},
[size=1em] };
[size=1em] list<people> peoplelist = people.where(func.compile()).tolist();
[size=1em]}
|
对象深拷贝 硬编码 [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
| [size=1em][size=1em]peoplecopy peoplecopy = new peoplecopy()
[size=1em]{
[size=1em] id = people.id,
[size=1em] name = people.name,
[size=1em] age = people.age
[size=1em]};
|
通过反射实现 [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
[size=1em]20
[size=1em]21
[size=1em]22
[size=1em]23
[size=1em]24
[size=1em]25
[size=1em]26
| [size=1em][size=1em]public class reflectionmapper
[size=1em]{
[size=1em] /// <summary>
[size=1em] /// 反射
[size=1em] /// </summary>
[size=1em] /// <typeparam name="tin"></typeparam>
[size=1em] /// <typeparam name="tout"></typeparam>
[size=1em] /// <param name="tin"></param>
[size=1em] /// <returns></returns>
[size=1em] public static tout trans<tin, tout>(tin tin)
[size=1em] {
[size=1em] tout tout = activator.createinstance<tout>();
[size=1em] foreach (var itemout in tout.gettype().getproperties())
[size=1em] {
[size=1em] var propin = tin.gettype().getproperty(itemout.name);
[size=1em] itemout.setvalue(tout, propin.getvalue(tin));
[size=1em] }
[size=1em] foreach (var itemout in tout.gettype().getfields())
[size=1em] {
[size=1em] var fieldin = tin.gettype().getfield(itemout.name);
[size=1em] itemout.setvalue(tout, fieldin.getvalue(tin));
[size=1em] }
[size=1em] return tout;
[size=1em] }
[size=1em]}
|
通过序列化实现 [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
| [size=1em][size=1em]/// <summary>
[size=1em]/// 使用第三方序列化反序列化工具
[size=1em]/// 还有automapper
[size=1em]/// </summary>
[size=1em]public class serializemapper
[size=1em]{
[size=1em] /// <summary>
[size=1em] /// 序列化反序列化方式
[size=1em] /// </summary>
[size=1em] /// <typeparam name="tin"></typeparam>
[size=1em] /// <typeparam name="tout"></typeparam>
[size=1em] public static tout trans<tin, tout>(tin tin)
[size=1em] {
[size=1em] return jsonconvert.deserializeobject<tout>(jsonconvert.serializeobject(tin));
[size=1em] }
[size=1em]}
|
反射和序列化两种实现方式性能不太好;
通过表达式目录树实现通过表达式目录树动态的生成硬编码 [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
| [size=1em][size=1em]func<people, peoplecopy> func = p => new peoplecopy()
[size=1em]{
[size=1em] id = p.id,
[size=1em] name = p.name,
[size=1em] age = p.age
[size=1em]};
[size=1em]peoplecopy peoplecopy3 = func.invoke(people);
|
方法一:普通缓存 [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
[size=1em]20
[size=1em]21
[size=1em]22
[size=1em]23
[size=1em]24
[size=1em]25
[size=1em]26
[size=1em]27
[size=1em]28
[size=1em]29
[size=1em]30
[size=1em]31
[size=1em]32
[size=1em]33
[size=1em]34
[size=1em]35
[size=1em]36
[size=1em]37
[size=1em]38
[size=1em]39
[size=1em]40
[size=1em]41
[size=1em]42
[size=1em]43
[size=1em]44
[size=1em]45
[size=1em]46
[size=1em]47
| [size=1em][size=1em]/// <summary>
[size=1em]/// 生成表达式目录树 缓存
[size=1em]/// </summary>
[size=1em]public class expressionmapper
[size=1em]{
[size=1em] /// <summary>
[size=1em] /// 字典缓存--hash分布
[size=1em] /// </summary>
[size=1em] private static dictionary<string, object> _dic = new dictionary<string, object>();
[size=1em] /// <summary>
[size=1em] /// 字典缓存表达式树
[size=1em] /// </summary>
[size=1em] /// <typeparam name="tin"></typeparam>
[size=1em] /// <typeparam name="tout"></typeparam>
[size=1em] /// <param name="tin"></param>
[size=1em] /// <returns></returns>
[size=1em] public static tout trans<tin, tout>(tin tin)
[size=1em] {
[size=1em] string key = string.format("funckey_{0}_{1}", typeof(tin).fullname, typeof(tout).fullname);
[size=1em] if (!_dic.containskey(key))
[size=1em] {
[size=1em] parameterexpression parameterexpression = expression.parameter(typeof(tin), "p");
[size=1em] list<memberbinding> memberbindinglist = new list<memberbinding>();
[size=1em] foreach (var item in typeof(tout).getproperties())
[size=1em] {
[size=1em] memberexpression property = expression.property(parameterexpression, typeof(tin).getproperty(item.name));
[size=1em] memberbinding memberbinding = expression.bind(item, property);
[size=1em] memberbindinglist.add(memberbinding);
[size=1em] }
[size=1em] foreach (var item in typeof(tout).getfields())
[size=1em] {
[size=1em] memberexpression property = expression.field(parameterexpression, typeof(tin).getfield(item.name));
[size=1em] memberbinding memberbinding = expression.bind(item, property);
[size=1em] memberbindinglist.add(memberbinding);
[size=1em] }
[size=1em] memberinitexpression memberinitexpression = expression.memberinit(expression.new(typeof(tout)), memberbindinglist.toarray());
[size=1em] expression<func<tin, tout>> lambda = expression.lambda<func<tin, tout>>(memberinitexpression, new parameterexpression[]
[size=1em] {
[size=1em] parameterexpression
[size=1em] });
[size=1em] func<tin, tout> func = lambda.compile();//拼装是一次性的
[size=1em] _dic[key] = func;
[size=1em] }
[size=1em] return ((func<tin, tout>)_dic[key]).invoke(tin);
[size=1em] }
[size=1em]}
|
方法二:泛型缓存,性能较高 [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
[size=1em]13
[size=1em]14
[size=1em]15
[size=1em]16
[size=1em]17
[size=1em]18
[size=1em]19
[size=1em]20
[size=1em]21
[size=1em]22
[size=1em]23
[size=1em]24
[size=1em]25
[size=1em]26
[size=1em]27
[size=1em]28
[size=1em]29
[size=1em]30
[size=1em]31
[size=1em]32
[size=1em]33
[size=1em]34
[size=1em]35
[size=1em]36
| [size=1em][size=1em]/// <summary>
[size=1em]/// 生成表达式目录树 泛型缓存
[size=1em]/// </summary>
[size=1em]/// <typeparam name="tin"></typeparam>
[size=1em]/// <typeparam name="tout"></typeparam>
[size=1em]public class expressiongenericmapper<tin, tout>//mapper`2
[size=1em]{
[size=1em] private static func<tin, tout> _func = null;
[size=1em] static expressiongenericmapper()
[size=1em] {
[size=1em] parameterexpression parameterexpression = expression.parameter(typeof(tin), "p");
[size=1em] list<memberbinding> memberbindinglist = new list<memberbinding>();
[size=1em] foreach (var item in typeof(tout).getproperties())
[size=1em] {
[size=1em] memberexpression property = expression.property(parameterexpression, typeof(tin).getproperty(item.name));
[size=1em] memberbinding memberbinding = expression.bind(item, property);
[size=1em] memberbindinglist.add(memberbinding);
[size=1em] }
[size=1em] foreach (var item in typeof(tout).getfields())
[size=1em] {
[size=1em] memberexpression property = expression.field(parameterexpression, typeof(tin).getfield(item.name));
[size=1em] memberbinding memberbinding = expression.bind(item, property);
[size=1em] memberbindinglist.add(memberbinding);
[size=1em] }
[size=1em] memberinitexpression memberinitexpression = expression.memberinit(expression.new(typeof(tout)), memberbindinglist.toarray());
[size=1em] expression<func<tin, tout>> lambda = expression.lambda<func<tin, tout>>(memberinitexpression, new parameterexpression[]
[size=1em] {
[size=1em] parameterexpression
[size=1em] });
[size=1em] _func = lambda.compile();//拼装是一次性的
[size=1em] }
[size=1em] public static tout trans(tin t)
[size=1em] {
[size=1em] return _func(t);
[size=1em] }
[size=1em]}
| 本贴来源:帖子
|