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();
}
}
}