using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace WCS.Core { public static class Extentions { static ConcurrentDictionary ExObjs = new ConcurrentDictionary(); public static T GetEx(object entity) { lock (ExObjs) { if (!ExObjs.ContainsKey(entity)) { var obj = Activator.CreateInstance(typeof(T), entity); ExObjs[entity] = obj; } return (T)ExObjs[entity]; } } public static PLC Ex(this PLCInfo source,World world) { return GetExOfWorld(source,world); } static ConcurrentDictionary> ExObjsOfWorld = new ConcurrentDictionary>(); static T GetExOfWorld(this object source, World world) { if (!ExObjsOfWorld.TryGetValue(world, out var objs)) { ExObjsOfWorld.TryAdd(world, new ConcurrentDictionary()); objs = ExObjsOfWorld[world]; } if (!objs.TryGetValue(source, out var obj)) { lock (objs) { if (!objs.ContainsKey(source)) { obj = Activator.CreateInstance(typeof(T), source, world); objs.TryAdd(source, obj); } obj = objs[source]; } } return (T)obj; } public static DataBlock Ex(this DBInfo source, World world) { return GetExOfWorld(source, world); } public static DataBlock[] GetDataBlocks(this World source) { ExObjsOfWorld.TryGetValue(source, out var dic); if (dic == null) return new DataBlock[0]; var res= dic.Values.OfType().ToArray(); return res; } public static WorldEx Ex(this World source) { return GetEx(source); } public static void AddSafe(this List source,T item) { lock (source) { source.Add(item); } } public static void AddSafe(this List source,IEnumerable item) { lock (source) { source.AddRange(item); } } public static string Description(this T source) where T : struct, Enum { var name = Enum.GetName(source); if (name == null) return source.ToString(); var f = source.GetType().GetField(name); var attr = f.GetCustomAttribute(); if (attr == null) return source.ToString(); else return attr.Description; } public static object Copy(this object source, Type t) { var obj=Activator.CreateInstance(t); foreach (var p in t.GetProperties()) { var p2 = source.GetType().GetProperty(p.Name); var value = p2.GetValue(source); p.SetValue(obj, value); } return obj; } public static T Copy(this object source) { return (T)source.Copy(typeof(T)); } } public static class BitExtension { #region ushort /// /// 设置指定位置的位值的值 /// /// ushort对象 /// 指定位置 /// 值 /// public static ushort SetBit(this ushort value, int position, bool flag) { return SetBits(value, position, 1, flag ? (byte)1 : (byte)0); } /// /// 批量设置指定位置的位值的值 /// /// ushort对象 /// 开始位置 /// 长度 /// 值 /// public static ushort SetBits(this ushort value, int position, int length, ushort bits) { if (length <= 0 || position >= 16) return value; var mask = (2 << (length - 1)) - 1; value &= (ushort)~(mask << position); value |= (ushort)((bits & mask) << position); return value; } /// /// 获取指定位置的值 /// /// ushort对象 /// 指定位置 /// public static bool GetBit(this ushort value, int position) { return GetBits(value, position, 1) == 1; } /// /// 批量获取指定位置的值 /// /// ushort对象 /// 开始位值 /// 长度 /// public static ushort GetBits(this ushort value, int position, int length) { if (length <= 0 || position >= 16) return 0; var mask = (2 << (length - 1)) - 1; return (ushort)((value >> position) & mask); } #endregion ushort #region byte /// /// 设置指定位置的值 /// /// byte对象 /// 指定位置 /// 设置值 /// public static byte SetBit(this byte value, int position, bool flag) { if (position >= 8) return value; var mask = (2 << (1 - 1)) - 1; value &= (byte)~(mask << position); value |= (byte)(((flag ? 1 : 0) & mask) << position); return value; } /// /// 获取指定位置的值 /// /// byte对象 /// 指定位置 /// public static bool GetBit(this byte value, int position) { if (position >= 8) return false; var mask = (2 << (1 - 1)) - 1; return (byte)((value >> position) & mask) == 1; } #endregion byte #region uint /// /// 设置指定位置的位值的值 /// /// uint对象 /// 指定位置 /// 值 /// public static uint SetBit(this uint value, int position, bool flag) { return SetBits(value, position, 1, flag ? (byte)1 : (byte)0); } /// /// 批量设置指定位置的位值的值 /// /// uint对象 /// 开始位置 /// 长度 /// 值 /// public static uint SetBits(this uint value, int position, int length, uint bits) { if (length <= 0 || position >= 32) return value; var mask = (2 << (length - 1)) - 1; value &= (uint)~(mask << position); value |= (uint)((bits & mask) << position); return value; } /// /// 获取指定位置的值 /// /// uint对象 /// 指定位置 /// public static bool GetBit(this uint value, int position) { return GetBits(value, position, 1) == 1; } /// /// 批量获取指定位置的值 /// /// uint对象 /// 开始位值 /// 长度 /// public static uint GetBits(this uint value, int position, int length) { if (length <= 0 || position >= 32) return 0; var mask = (2 << (length - 1)) - 1; return (uint)((value >> position) & mask); } #endregion uint #region ulong /// /// 设置指定位置的位值的值 /// /// ulong对象 /// 指定位置 /// 值 /// public static ulong SetBit(this ulong value, int position, bool flag) { return SetBits(value, position, 1, flag ? (byte)1 : (byte)0); } /// /// 批量设置指定位置的位值的值 /// /// ulong对象 /// 开始位置 /// 长度 /// 值 /// public static ulong SetBits(this ulong value, int position, int length, ulong bits) { if (length <= 0 || position >= 64) return value; var mask = (ulong)(2 << (length - 1)) - 1; value &= ~(mask << position); value |= (bits & mask) << position; return value; } /// /// 获取指定位置的值 /// /// ulong对象 /// 指定位置 /// public static bool GetBit(this ulong value, int position) { return GetBits(value, position, 1) == 1; } /// /// 批量获取指定位置的值 /// /// ulong对象 /// 开始位值 /// 长度 /// public static ulong GetBits(this ulong value, int position, int length) { if (length <= 0 || position >= 64) return 0; var mask = (ulong)(2 << (length - 1)) - 1; return (value >> position) & mask; } #endregion ulong } public static class ExpressionExtensions { public static string ExpToString(this LambdaExpression source) { var str = ""; try { str = LambdaToString(source); } catch { str = source.ToString(); } var arr = str.Split("Convert("); arr = arr.Select(v => { if (!v.Contains(',')) return v; var index = v.IndexOf(','); var index2 = v.IndexOf(')', index); var sub = v.Substring(index, index2 - index + 1); var str = v.Replace(sub, ""); return str; }).ToArray(); var res = string.Join("", arr); return res; } public static string LambdaToString(LambdaExpression expression) { var replacements = new Dictionary(); WalkExpression(replacements, expression); string body = expression.ToString(); foreach (var parm in expression.Parameters) { var parmName = parm.Name; var parmTypeName = parm.Type.Name; body = body.Replace(parmName + " =>", "(" + parmTypeName + " v) =>"); } foreach (var replacement in replacements) { body = body.Replace(replacement.Key, replacement.Value); } return body; } private static void WalkExpression(Dictionary replacements, Expression expression) { switch (expression.NodeType) { case ExpressionType.MemberAccess: string replacementExpression = expression.ToString(); if (replacementExpression.Contains("value(")) { string replacementValue = Expression.Lambda(expression).Compile().DynamicInvoke().ToString(); if (!replacements.ContainsKey(replacementExpression)) { replacements.Add(replacementExpression, replacementValue.ToString()); } } break; case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.OrElse: case ExpressionType.AndAlso: case ExpressionType.Equal: case ExpressionType.NotEqual: var bexp = expression as BinaryExpression; WalkExpression(replacements, bexp.Left); WalkExpression(replacements, bexp.Right); break; case ExpressionType.Call: var mcexp = expression as MethodCallExpression; foreach (var argument in mcexp.Arguments) { WalkExpression(replacements, argument); } break; case ExpressionType.Lambda: var lexp = expression as LambdaExpression; WalkExpression(replacements, lexp.Body); break; case ExpressionType.Constant: //do nothing break; case ExpressionType.Convert: var exp = expression as UnaryExpression; WalkExpression(replacements, exp.Operand); break; default: //Trace.WriteLine("Unknown type"); break; } } static bool When(this T source, Expression> exp) where T : class { var str = exp.ExpToString(); try { var res = exp.Compile().Invoke(source); str += res ? " 成立" : " 不成立"; return res; } catch (Exception ex) { str += ex.GetBaseException().Message; throw; } finally { Console.WriteLine(str); Console.WriteLine("------------------------------------"); } } } }