using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using MECF.Framework.RT.EquipmentLibrary.Core.Attributes; namespace MECF.Framework.RT.EquipmentLibrary.Core.Extensions { public static class BitTypeClassExtension { /// /// 返回类型中以标记的公共属性。 /// /// /// private static List GetProperties(IReflect type) { var piList = type .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(x => x.PropertyType == typeof(bool) && x.GetCustomAttributes(true) .OfType() .Any()); return piList.ToList(); } /// /// 将整数转换为包含Bit定义的类。 /// 注意: /// 目标类中和输入整数bit对应的属性需要用标记。 /// /// 包含Bit属性定义的类的类型。 /// 待转换的整数。 /// 有效的位长度。 /// public static T ToBitTypeClass(this int bitValueSource, int bitLen) where T : new() { var obj = new T(); for (var i = 0; i < bitLen; i++) { var pi = typeof(T) .GetProperties(BindingFlags.Public | BindingFlags.Instance) .FirstOrDefault(x => x.PropertyType == typeof(bool) && x.GetCustomAttributes(true) .OfType() .Any(a => a.BitIndex == i)); if (pi != null) { pi.SetValue(obj, (bitValueSource & (1 << i)) != 0 ? true : false); } } return (T)obj; } /// /// 将BitType对象中以标记的属性合并整理为int。 /// /// 包含Bit属性定义的类的类型。 /// 对象实例。 /// public static int FromBitTypeClass(this T obj) { var piList = GetProperties(typeof(T)); if (!piList.Any()) return -1; var integValue = 0; foreach (var pi in piList) { // 如果该属性没有用BitTypeClassPropertyAttribute标记,则忽略 if (!(pi.GetCustomAttribute(typeof(BitTypeClassPropertyAttribute)) is BitTypeClassPropertyAttribute attr)) continue; // 如果该属性的返回值不是bool型,则忽略 if (!(pi.GetValue(obj) is bool v)) continue; // 如果该属性为True,则将返回整数的指定Bit设置为1. if(v) integValue |= (1 << attr.BitIndex); } return integValue; } /// /// 从BitType类聚合错误信息。 /// /// /// /// public static List AggregateErrorMessages(this T obj) { var piList = GetProperties(typeof(T)); var piForError = piList.Where(pi => pi.GetCustomAttributes() .OfType() .Any(a => a.IsErrorBit)) .ToList(); var errs = new List(); foreach (var pi in piForError) { if (!(pi.GetValue(obj) is bool vv)) continue; if (!vv) continue; var attr = pi.GetCustomAttribute( typeof(BitTypeClassPropertyAttribute)) as BitTypeClassPropertyAttribute; errs.Add(attr?.Message??$"Cannot get message from {nameof(BitTypeClassPropertyAttribute)} of property {pi.Name} of object {obj}"); } return errs; } } }