CreateValidateStringRequiredExp(){return (name, value) =>string.IsNullOrEmpty(value)? ValidateResult.Error($"missing {name}"): ValidateResult.Ok();}private static Expression CreateValidateStringMinLengthExp(int minLength){return (name, value) =>value.Length < minLength? ValidateResult.Error($"Length of {name} should be great than {minLength}"): ValidateResult.Ok();}}}代码要点:
- CreateValidateStringMinLengthExp 静态方法 , 传入一个参数创建得到一个和 CreateValidateStringRequiredExp 返回值一样的表达式 。 对比上一节中的 ValidateStringMinLengthExp, 实现了固定 int 参数而得到一个新表达式的操作 。 这就是一种柯理化的体现 。
- 为了统一都采用静态方法 , 我们将上一节中的 ValidateStringRequiredExp 也改为 CreateValidateStringRequiredExp 静态方法 , 这仅仅只是为了看起来一致(但实际上增加了一点点开销 , 因为没必要重复创建一个不变的表达式) 。
- 相应的调整一下 List 组装过程的代码 。
第八步 , 合并重复代码本节 , 我们将合并 CreateValidateStringRequiredExpression 和 CreateValidateStringMinLengthExpression 中重复的代码 。
其中只有 requiredMethodExp 的创建方式不同 。 因此 , 只要将这个参数从方法外面传入就可以抽离出公共部分 。
using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Diagnostics;using System.Linq;using System.Linq.Expressions;using System.Reflection;using FluentAssertions;using NUnit.Framework;// ReSharper disable InvalidXmlDocCommentnamespace Newbe.ExpressionsTests{////// Refactor to CreateValidateExpression///public class X03PropertyValidationTest08{private const int Count = 10_000;private static Func _func;[SetUp]public void Init(){try{var finalExpression = CreateCore();_func = finalExpression.Compile();Expression> CreateCore(){// exp for inputvar inputExp = Expression.Parameter(typeof(CreateClaptrapInput), "input");// exp for outputvar resultExp = Expression.Variable(typeof(ValidateResult), "result");// exp for return statementvar returnLabel = Expression.Label(typeof(ValidateResult));var innerExps = new List {CreateDefaultResult()};var stringProps = typeof(CreateClaptrapInput).GetProperties().Where(x => x.PropertyType == typeof(string));foreach (var propertyInfo in stringProps){if (propertyInfo.GetCustomAttribute() != null){innerExps.Add(CreateValidateStringRequiredExpression(propertyInfo));}var minlengthAttribute = propertyInfo.GetCustomAttribute();if (minlengthAttribute != null){innerExps.Add(CreateValidateStringMinLengthExpression(propertyInfo, minlengthAttribute.Length));}}innerExps.Add(Expression.Label(returnLabel, resultExp));// build whole blockvar body = Expression.Block(new[] {resultExp},innerExps);// build lambda from bodyvar final = Expression.Lambda>(body,inputExp);return final;Expression CreateDefaultResult(){var okMethod = typeof(ValidateResult).GetMethod(nameof(ValidateResult.Ok));Debug.Assert(okMethod != null, nameof(okMethod) + " != null");var methodCallExpression = Expression.Call(okMethod);var re = Expression.Assign(resultExp, methodCallExpression);/*** final as:* result = ValidateResult.Ok()*/return re;}Expression CreateValidateStringRequiredExpression(PropertyInfo propertyInfo)=> CreateValidateExpression(propertyInfo,CreateValidateStringRequiredExp());Expression CreateValidateStringMinLengthExpression(PropertyInfo propertyInfo,int minlengthAttributeLength)=> CreateValidateExpression(propertyInfo,CreateValidateStringMinLengthExp(minlengthAttributeLength));Expression CreateValidateExpression(PropertyInfo propertyInfo,Expression
推荐阅读
-
-
人民日报微信公号|这个电话是警察打来的,一定要接!
-
一起来宠花|10种多肉美人,养护简单颜值高,适合新手,值得拥有!
-
芈八子跟义渠王真的有关系吗,芈月杀了义渠王的儿子吗-
-
光明网|高温下铁路“编程师”戴双层手套 扒车作业就像抓热锅柄
-
欧联杯|曼联30岁弃将正式告别罗马:欧联杯不踢了 下赛季去国米?
-
爱尔兰_时政|违反爱尔兰防疫规定引发众怒,欧盟贸易专员宣布主动辞职
-
居家分享孜然鸡翅的好吃做法,外焦里嫩,鲜香味美,家人都爱吃
-
「耀小哥」如能熟练掌握,国标省标让你拿到手软,东皇太一的高阶玩法
-
朴恩斌|韩国女星朴恩斌深夜自PO美腿照,60万粉丝刷爱心
-
幽默段子|201017,非常适合做网格的科技指数---科技ETF
-
-
深具哲理意趣的一首唐诗:逢人不说人间事,便是人间无事人
-
极速聊科技 14:iCloud 钥匙串加入了对用户密码安全强度与数据泄漏等相关改进,iOS
-
每日谈资|今日欧美圈:哈卷将出演惊悚电影,黛米未婚夫曾暗恋赛琳娜?
-
i黑马|发力电商数字化供应链服务,闪卖侠完成新一轮融资
-
-
-
王者解说|姿态在上海买得起房,Mlxg投去羡慕的目光:乌兹周围住的都是明星
-
狂买550枚先进导弹▲一口气狂买550枚先进导弹,印度这是要……