using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Vanara.PInvoke { /// Gets a static field's name from its value and caches the list for faster lookups. public class StaticFieldValueHash { private static Dictionary<(Type, Type), IDictionary> cache = new Dictionary<(Type, Type), IDictionary>(); /// Tries to get the name of a static field from it's value. /// The type of the type. /// The type of the field type. /// The value for which to search. /// On success, the name of the field. /// if the value was found, otherwise . public static bool TryGetFieldName(TFieldType value, out string fieldName) { var tt = (typeof(TType), typeof(TFieldType)); if (!cache.TryGetValue(tt, out var hash)) cache.Add(tt, hash = typeof(TType).GetFields(BindingFlags.Public | BindingFlags.Static).Where(fi => fi.FieldType == typeof(TFieldType)).Distinct(FIValueComp.Default).ToDictionary(fi => fi.GetValue(null).GetHashCode(), fi => fi.Name)); return hash.TryGetValue(value.GetHashCode(), out fieldName); } private class FIValueComp : IEqualityComparer { bool IEqualityComparer.Equals(FieldInfo x, FieldInfo y) => Comparer.Default.Compare((TFieldType)x.GetValue(null), (TFieldType)y.GetValue(null)) == 0; int IEqualityComparer.GetHashCode(FieldInfo obj) => ((TFieldType)obj.GetValue(null)).GetHashCode(); public static readonly FIValueComp Default = new FIValueComp(); } } }