#nullable disable using System; using System.Linq; using System.Collections.Generic; using System.ComponentModel; using System.Reflection; namespace BizHawk.Common.ReflectionExtensions { /// /// Reflection based helper methods /// public static class ReflectionExtensions { public static IEnumerable GetPropertiesWithAttrib(this Type type, Type attributeType) { return type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic) .Where(p => p.GetCustomAttributes(attributeType, false).Length > 0); } public static IEnumerable GetMethodsWithAttrib(this Type type, Type attributeType) { return type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic) .Where(p => p.GetCustomAttributes(attributeType, false).Length > 0); } /// /// Gets the description attribute from an object /// public static string GetDescription(this object obj) { var type = obj.GetType(); var memInfo = type.GetMember(obj.ToString()); if (memInfo.Length > 0) { var attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); if (attrs.Length > 0) { return ((DescriptionAttribute)attrs[0]).Description; } } return obj.ToString(); } /// /// Returns the DisplayName attribute value if it exists, else the name of the class /// public static string DisplayName(this Type type) { var displayName = (DisplayNameAttribute)type .GetCustomAttributes(typeof(DisplayNameAttribute), false) .FirstOrDefault(); if (displayName != null) { return displayName.DisplayName; } return type.Name; } /// /// Gets the description attribute from a type /// public static string Description(this Type type) { var descriptions = (DescriptionAttribute[]) type.GetCustomAttributes(typeof(DescriptionAttribute), false); if (descriptions.Length == 0) { return ""; } return descriptions[0].Description; } /// /// Gets an enum from a description attribute /// /// The description attribute value /// The type of the enum /// An enum value with the given description attribute, if no suitable description is found then a default value of the enum is returned /// does not inherit /// implementation from https://stackoverflow.com/a/4367868/7467292 public static T GetEnumFromDescription(this string description) { var type = typeof(T); if (!type.IsEnum) { throw new InvalidOperationException(); } foreach (var field in type.GetFields()) { if (Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute attribute) { if (attribute.Description == description) { return (T)field.GetValue(null); } } else { if (field.Name == description) { return (T)field.GetValue(null); } } } return default(T); } /// /// Takes an enum Type and generates a list of strings from the description attributes /// public static IEnumerable GetEnumDescriptions(this Type type) { var vals = Enum.GetValues(type); foreach (var v in vals) { yield return v.GetDescription(); } } public static T GetAttribute(this object o) { return (T)o.GetType().GetCustomAttributes(typeof(T), false)[0]; } } }