#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];
}
}
}