mirror of
https://github.com/oliverbooth/X10D
synced 2024-11-22 23:58:48 +00:00
parent
f980ade3a8
commit
28f46ecc8d
11
X10D/src/ExceptionMessages.cs
Normal file
11
X10D/src/ExceptionMessages.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace X10D
|
||||||
|
{
|
||||||
|
internal static class ExceptionMessages
|
||||||
|
{
|
||||||
|
public static readonly string TypeDoesNotInheritAttribute = $"{{0}} does not inherit {typeof(Attribute)}";
|
||||||
|
public static readonly string TypeIsNotClass = $"{{0}} is not a class";
|
||||||
|
public static readonly string TypeIsNotInterface = $"{{0}} is not an interface";
|
||||||
|
}
|
||||||
|
}
|
@ -1,123 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace X10D
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Extension methods for various reflection types.
|
|
||||||
/// </summary>
|
|
||||||
public static class ReflectionExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the value set in this member's annotated <see cref="DefaultValueAttribute" />, or
|
|
||||||
/// <see langword="default" /> if none exists.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="member">The member.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// Returns an <see cref="object" /> representing the value stored in this member's
|
|
||||||
/// <see cref="DefaultValueAttribute" />.
|
|
||||||
/// </returns>
|
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="member" /> is <see langword="null" />.</exception>
|
|
||||||
public static object GetDefaultValue(this MemberInfo member)
|
|
||||||
{
|
|
||||||
if (member is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(member));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(member.GetCustomAttribute<DefaultValueAttribute>() is { } attribute))
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
return attribute.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the value set in this member's annotated <see cref="DefaultValueAttribute" />, or
|
|
||||||
/// <see langword="default" /> if none exists.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type to which the value should cast.</typeparam>
|
|
||||||
/// <param name="member">The member.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// Returns an instance of <typeparamref name="T" /> representing the value stored in this member's
|
|
||||||
/// <see cref="DefaultValueAttribute" />.
|
|
||||||
/// </returns>
|
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="member" /> is <see langword="null" />.</exception>
|
|
||||||
public static T GetDefaultValue<T>(this MemberInfo member)
|
|
||||||
{
|
|
||||||
if (member is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(member));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (T)member.GetDefaultValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the value set in this member's annotated <see cref="DescriptionAttribute" />, or
|
|
||||||
/// <see langword="null" /> if none exists.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="member">The member.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// Returns a string representing the value stored in this member's
|
|
||||||
/// <see cref="DescriptionAttribute" />.
|
|
||||||
/// </returns>
|
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="member" /> is <see langword="null" />.</exception>
|
|
||||||
public static string GetDescription(this MemberInfo member)
|
|
||||||
{
|
|
||||||
if (member is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(member));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(member.GetCustomAttribute<DescriptionAttribute>() is { } attribute))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return attribute.Description;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves a custom attribute of a specified type that is applied to the specified member, and passes it
|
|
||||||
/// to a selector delegate in order to select one or more the members in the attribute.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TAttribute">The attribute type.</typeparam>
|
|
||||||
/// <typeparam name="TReturn">The return type of the <paramref name="selector" /> delegate.</typeparam>
|
|
||||||
/// <param name="member">The member.</param>
|
|
||||||
/// <param name="selector">The selector delegate.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// Returns an instance of <typeparamref name="TReturn" /> as provided from
|
|
||||||
/// <paramref name="selector" />.
|
|
||||||
/// </returns>
|
|
||||||
/// <exception cref="ArgumentNullException">
|
|
||||||
/// <paramref name="member" /> is <see langword="null" />
|
|
||||||
/// -or-
|
|
||||||
/// <paramref name="selector" /> is <see langword="null" />.
|
|
||||||
/// </exception>
|
|
||||||
public static TReturn SelectFromCustomAttribute<TAttribute, TReturn>(
|
|
||||||
this MemberInfo member,
|
|
||||||
Func<TAttribute, TReturn> selector)
|
|
||||||
where TAttribute : Attribute
|
|
||||||
{
|
|
||||||
if (member is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(member));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selector is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(selector));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(member.GetCustomAttribute<TAttribute>() is { } attribute))
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
return selector(attribute);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
98
X10D/src/ReflectionExtensions/MemberInfoExtensions.cs
Normal file
98
X10D/src/ReflectionExtensions/MemberInfoExtensions.cs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace X10D.ReflectionExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods for <see cref="MemberInfo" />.
|
||||||
|
/// </summary>
|
||||||
|
public static class MemberInfoExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether or not the current member has been decorated with a specified attribute.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="member">The member attributes to check.</param>
|
||||||
|
/// <typeparam name="T">The attribute type.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if the current member has been decorated with a specified attribute, or
|
||||||
|
/// <see langword="false" /> otherwise.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="member" /> is <see langword="null" />.</exception>
|
||||||
|
public static bool HasCustomAttribute<T>(this MemberInfo member)
|
||||||
|
where T : Attribute
|
||||||
|
{
|
||||||
|
if (member is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(member));
|
||||||
|
}
|
||||||
|
|
||||||
|
return member.HasCustomAttribute(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether or not the current member has been decorated with a specified attribute.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="member">The member attributes to check.</param>
|
||||||
|
/// <param name="attribute">The attribute type.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if the current member has been decorated with a specified attribute, or
|
||||||
|
/// <see langword="false" /> otherwise.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="member" /> is <see langword="null" />.</exception>
|
||||||
|
public static bool HasCustomAttribute(this MemberInfo member, Type attribute)
|
||||||
|
{
|
||||||
|
if (member is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(member));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attribute is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(attribute));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attribute.Inherits<Attribute>())
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format(CultureInfo.CurrentCulture, ExceptionMessages.TypeDoesNotInheritAttribute, attribute),
|
||||||
|
nameof(attribute));
|
||||||
|
}
|
||||||
|
|
||||||
|
return member.GetCustomAttribute(attribute) is not null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a custom attribute that is decorated by the current member, and projects it into to a new form.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TAttribute">The attribute type.</typeparam>
|
||||||
|
/// <typeparam name="TReturn">The return type of the <paramref name="selector" /> delegate.</typeparam>
|
||||||
|
/// <param name="type">The member.</param>
|
||||||
|
/// <param name="selector">A transform function to apply to the attribute.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// An instance of <typeparamref name="TReturn" /> as provided from <paramref name="selector" />.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="type" /> is <see langword="null" />
|
||||||
|
/// -or-
|
||||||
|
/// <paramref name="selector" /> is <see langword="null" />.
|
||||||
|
/// </exception>
|
||||||
|
public static TReturn? SelectFromCustomAttribute<TAttribute, TReturn>(this MemberInfo type, Func<TAttribute, TReturn> selector)
|
||||||
|
where TAttribute : Attribute
|
||||||
|
{
|
||||||
|
if (type is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selector is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(selector));
|
||||||
|
}
|
||||||
|
|
||||||
|
return type.GetCustomAttribute<TAttribute>() is { } attribute
|
||||||
|
? selector(attribute)
|
||||||
|
: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
190
X10D/src/ReflectionExtensions/TypeExtensions.cs
Normal file
190
X10D/src/ReflectionExtensions/TypeExtensions.cs
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace X10D.ReflectionExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods for <see cref="Type" />.
|
||||||
|
/// </summary>
|
||||||
|
public static class TypeExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether or not the current type has been decorated with a specified attribute.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The type whose attributes to check.</param>
|
||||||
|
/// <typeparam name="T">The attribute type.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if the current type has been decorated with a specified attribute, or
|
||||||
|
/// <see langword="false" /> otherwise.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="type" /> is <see langword="null" />.</exception>
|
||||||
|
public static bool HasCustomAttribute<T>(this Type type)
|
||||||
|
where T : Attribute
|
||||||
|
{
|
||||||
|
if (type is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return type.HasCustomAttribute(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether or not the current type has been decorated with a specified attribute.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The type whose attributes to check.</param>
|
||||||
|
/// <param name="attribute">The attribute type.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if the current type has been decorated with a specified attribute, or
|
||||||
|
/// <see langword="false" /> otherwise.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="type" /> is <see langword="null" />.</exception>
|
||||||
|
public static bool HasCustomAttribute(this Type type, Type attribute)
|
||||||
|
{
|
||||||
|
if (type is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attribute is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(attribute));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attribute.Inherits<Attribute>())
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format(CultureInfo.CurrentCulture, ExceptionMessages.TypeDoesNotInheritAttribute, attribute),
|
||||||
|
nameof(attribute));
|
||||||
|
}
|
||||||
|
|
||||||
|
return type.GetCustomAttribute(attribute) is not null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether the current type implements a specified interface.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The type whose interface list to check.</param>
|
||||||
|
/// <typeparam name="T">The interface type.</typeparam>
|
||||||
|
/// <returns><see langword="true" /> if the current exists on the type, or <see langword="false" /> otherwise.</returns>
|
||||||
|
public static bool Implements<T>(this Type value)
|
||||||
|
{
|
||||||
|
return value.Implements(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether the current type implements a specified interface.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The type whose interface list to check.</param>
|
||||||
|
/// <param name="interfaceType">The interface type.</param>
|
||||||
|
/// <returns><see langword="true" /> if the current exists on the type, or <see langword="false" /> otherwise.</returns>
|
||||||
|
public static bool Implements(this Type value, Type interfaceType)
|
||||||
|
{
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interfaceType is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(interfaceType));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interfaceType.IsInterface)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format(CultureInfo.CurrentCulture, ExceptionMessages.TypeIsNotInterface, interfaceType),
|
||||||
|
nameof(interfaceType));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.IndexOf(value.GetInterfaces(), interfaceType) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether the current type inherits a specified type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The type whose interface list to check.</param>
|
||||||
|
/// <typeparam name="T">The base type.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if the current type inherits <typeparamref name="T" />, or <see langword="false" />
|
||||||
|
/// otherwise.
|
||||||
|
/// </returns>
|
||||||
|
public static bool Inherits<T>(this Type value)
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
return value.Inherits(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether the current type inherits a specified type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The type whose interface list to check.</param>
|
||||||
|
/// <param name="type">The base type.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if the current type inherits <paramref name="type" />, or <see langword="false" />
|
||||||
|
/// otherwise.
|
||||||
|
/// </returns>
|
||||||
|
public static bool Inherits(this Type value, Type type)
|
||||||
|
{
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value.IsClass)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format(CultureInfo.CurrentCulture, ExceptionMessages.TypeIsNotClass, value),
|
||||||
|
nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!type.IsClass)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format(CultureInfo.CurrentCulture, ExceptionMessages.TypeIsNotClass, type),
|
||||||
|
nameof(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.IsSubclassOf(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a custom attribute that is decorated by the current type, and projects it into to a new form.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TAttribute">The attribute type.</typeparam>
|
||||||
|
/// <typeparam name="TReturn">The return type of the <paramref name="selector" /> delegate.</typeparam>
|
||||||
|
/// <param name="type">The type.</param>
|
||||||
|
/// <param name="selector">A transform function to apply to the attribute.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// An instance of <typeparamref name="TReturn" /> as provided from <paramref name="selector" />.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="type" /> is <see langword="null" />
|
||||||
|
/// -or-
|
||||||
|
/// <paramref name="selector" /> is <see langword="null" />.
|
||||||
|
/// </exception>
|
||||||
|
public static TReturn? SelectFromCustomAttribute<TAttribute, TReturn>(this Type type, Func<TAttribute, TReturn> selector)
|
||||||
|
where TAttribute : Attribute
|
||||||
|
{
|
||||||
|
if (type is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selector is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(selector));
|
||||||
|
}
|
||||||
|
|
||||||
|
return type.GetCustomAttribute<TAttribute>() is { } attribute
|
||||||
|
? selector(attribute)
|
||||||
|
: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user