Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../Core/Extensions/BitTypeClassExtension.cs

128 lines
4.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 返回类型中以<see cref="BitTypeClassPropertyAttribute"/>标记的公共属性。
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static List<PropertyInfo> GetProperties(IReflect type)
{
var piList = type
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.PropertyType == typeof(bool) &&
x.GetCustomAttributes(true)
.OfType<BitTypeClassPropertyAttribute>()
.Any());
return piList.ToList();
}
/// <summary>
/// 将整数转换为包含Bit定义的类。
/// <para>注意:</para>
/// <para>目标类中和输入整数bit对应的属性需要用<see cref="BitTypeClassPropertyAttribute"/>标记。</para>
/// </summary>
/// <typeparam name="T">包含Bit属性定义的类的类型。</typeparam>
/// <param name="bitValueSource">待转换的整数。</param>
/// <param name="bitLen">有效的位长度。</param>
/// <returns></returns>
public static T ToBitTypeClass<T>(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<BitTypeClassPropertyAttribute>()
.Any(a => a.BitIndex == i));
if (pi != null)
{
pi.SetValue(obj, (bitValueSource & (1 << i)) != 0 ? true : false);
}
}
return (T)obj;
}
/// <summary>
/// 将BitType对象中以<see cref="BidArgumentTypeAttribute"/>标记的属性合并整理为int。
/// </summary>
/// <typeparam name="T">包含Bit属性定义的类的类型。</typeparam>
/// <param name="obj">对象实例。</param>
/// <returns></returns>
public static int FromBitTypeClass<T>(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;
}
/// <summary>
/// 从BitType类聚合错误信息。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static List<string> AggregateErrorMessages<T>(this T obj)
{
var piList = GetProperties(typeof(T));
var piForError = piList.Where(pi =>
pi.GetCustomAttributes()
.OfType<BitTypeClassPropertyAttribute>()
.Any(a => a.IsErrorBit))
.ToList();
var errs = new List<string>();
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;
}
}
}