using Common.Extensions; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; namespace Common.Tools { /// /// 脏字过滤委托实现 /// /// public static class StrFilteFun { /// /// 脏字过滤委托 /// public static Func FilterCode = StrFilteFun.Generate(); private static T FilterCodeJump(T t, string[] s) => FilterCode(t, s); /// /// 循环处理 /// /// /// /// /// public static Expression ForEach(Expression collection, ParameterExpression loopVar, Expression loopContent) { var elementType = loopVar.Type; var enumerableType = typeof(IEnumerable<>).MakeGenericType(elementType); var enumeratorType = typeof(IEnumerator<>).MakeGenericType(elementType); var enumeratorVar = Expression.Variable(enumeratorType, "enumerator"); var getEnumeratorCall = Expression.Call(collection, enumerableType.GetMethod("GetEnumerator")); var enumeratorAssign = Expression.Assign(enumeratorVar, getEnumeratorCall); // The MoveNext method's actually on IEnumerator, not IEnumerator var moveNextCall = Expression.Call(enumeratorVar, typeof(IEnumerator).GetMethod("MoveNext")); var breakLabel = Expression.Label("LoopBreak"); var loop = Expression.Block(new[] { enumeratorVar }, enumeratorAssign, Expression.Loop( Expression.IfThenElse( Expression.Equal(moveNextCall, Expression.Constant(true)), Expression.Block(new[] { loopVar }, Expression.Assign(loopVar, Expression.Property(enumeratorVar, "Current")), loopContent ), Expression.Break(breakLabel) ), breakLabel) ); return loop; } public static Expression For(ParameterExpression loopVar, Expression initValue, Expression condition, Expression increment, Expression loopContent) { var initAssign = Expression.Assign(loopVar, initValue); var breakLabel = Expression.Label("LoopBreak"); var loop = Expression.Block(new[] { loopVar }, initAssign, Expression.Loop( Expression.IfThenElse( condition, Expression.Block( loopContent, increment ), Expression.Break(breakLabel) ), breakLabel) ); return loop; } /// ///委托过滤实现 /// /// public static Func Generate() { var type = typeof(T); var instance = Expression.Parameter(type); var strArray = Expression.Parameter(typeof(string[])); var returnLable = Expression.Label(type); if (type == typeof(string))//数类型是string return Expression.Lambda>( Expression.Block( Expression.Call(StrFilteTools._StrFilter, instance, strArray) ), instance, strArray).Compile(); List expressions = new List(); //数据类型是list if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>) || type.GetInterfaces().ToList().Where(e => e.IsGenericType && e.GetGenericTypeDefinition() == typeof(IList<>)).Any()) { var loopVar = Expression.Parameter(typeof(int)); var loopContent = Expression.Assign(Expression.MakeIndex(instance, type.GetProperty("Item"), new[] { loopVar }), Expression.Call(typeof(StrFilteFun<>).MakeGenericType(type.GetGenericArguments()[0]).GetMethod(nameof(FilterCodeJump), BindingFlags.NonPublic | BindingFlags.Static), Expression.MakeIndex(instance, type.GetProperty("Item"), new[] { loopVar }), strArray)); var @for = For(loopVar, Expression.Constant(0), Expression.LessThan(loopVar, Expression.Property(instance, type.GetProperty("Count"))), Expression.PostIncrementAssign(loopVar), loopContent); return Expression.Lambda>(Expression.Block( @for , (Expression)Expression.Return(returnLable, instance) , (Expression)Expression.Label(returnLable, instance) ), instance, strArray).Compile(); } var pros = type.GetProperties(); var fieds = type.GetFields(); foreach (var item in pros) { try { ///list 有属性是list的情况 /// var member = Expression.Property(instance, item); if (item.PropertyType == typeof(string) || item.PropertyType == typeof(List) || item.PropertyType.IsGenericType && item.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>) || item.PropertyType.GetInterfaces().ToList().Where(e => e.IsGenericType && e.GetGenericTypeDefinition() == typeof(IEnumerable<>)).Any()) { var call = Expression.Call(typeof(StrFilteFun<>).MakeGenericType(item.PropertyType).GetMethod(nameof(FilterCodeJump), BindingFlags.NonPublic | BindingFlags.Static), member, strArray); var ifNotNull = Expression.IfThen(Expression.NotEqual(member, Expression.Constant(null, item.PropertyType)), Expression.Assign(member, call)); expressions.Add(ifNotNull); } } catch { } } foreach (var item in fieds)// { try { if (item.FieldType == typeof(string)) { var member = Expression.Field(instance, item); var ifNotNull = Expression.IfThen(Expression.NotEqual(member, Expression.Constant(null, typeof(string))), Expression.Assign(member, Expression.Call(StrFilteTools._StrFilter, member, strArray))); expressions.Add(ifNotNull); } } catch { } } expressions.Add(Expression.Return(returnLable, instance)); expressions.Add(Expression.Label(returnLable, instance)); return Expression.Lambda>(Expression.Block(expressions.ToArray()), instance, strArray).Compile(); } } /// ///脏字过滤 /// public static class StrFilteTools { /// /// 脏字数据List /// public static MethodInfo _StrFilter = typeof(StrFilteTools).GetMethod(nameof(StrFilter), BindingFlags.Static | BindingFlags.Public); /// /// 批量数据过滤 /// /// 要过滤操作的字符串 /// 过滤脏字列表 /// public static string StrFilter(string value, string[] Filterlist) { var v = value; foreach (var item in Filterlist) { if (!item.IsNull()) { v = v.Replace(item, "*"); } } return v; } } }