// The Nova Project by Ken Beckett.
// Copyright (C) 2007-2012 Inevitable Software, all rights reserved.
// Released under the Common Development and Distribution License, CDDL-1.0: http://opensource.org/licenses/cddl1.php
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Nova.Utilities
{
/// <summary>
/// Static helper methods for <see cref="MemberInfo"/>.
/// </summary>
public static class MemberInfoUtil
{
#region /* STATIC HELPER METHODS */
/// <summary>
/// Determine if the MemberInfo has a custom attribute.
/// </summary>
/// <remarks>
/// This method must be used instead of the built-in GetCustomAttributes() call when working with
/// members of reflection-only assemblies (otherwise, the custom attribute type would be instantiated,
/// which is illegal).
/// </remarks>
public static bool HasCustomAttribute(MemberInfo thisMemberInfo, string name)
{
return Enumerable.Any(CustomAttributeData.GetCustomAttributes(thisMemberInfo), delegate(CustomAttributeData customAttribute) { return customAttribute.Constructor.DeclaringType != null && customAttribute.Constructor.DeclaringType.Name == name; });
}
/// <summary>
/// Get all custom attributes with the specified name from the MemberInfo.
/// </summary>
/// <remarks>
/// This method must be used instead of the built-in GetCustomAttributes() call when working with
/// reflection-only assemblies (otherwise, the custom attribute type would be instantiated, which is illegal).
/// </remarks>
public static List<CustomAttributeData> GetCustomAttributes(MemberInfo thisMemberInfo, string name)
{
return Enumerable.ToList(Enumerable.Where(CustomAttributeData.GetCustomAttributes(thisMemberInfo),
delegate(CustomAttributeData customAttribute) { return customAttribute.Constructor.DeclaringType != null && customAttribute.Constructor.DeclaringType.Name == name; }));
}
/// <summary>
/// Get the custom attribute with the specified name from the MemberInfo. If there are multiple attributes with the name, the first one is returned.
/// </summary>
/// <remarks>
/// This method must be used instead of the built-in GetCustomAttributes() call when working with
/// reflection-only assemblies (otherwise, the custom attribute type would be instantiated, which is illegal).
/// </remarks>
public static CustomAttributeData GetCustomAttribute(MemberInfo thisMemberInfo, string name)
{
return Enumerable.FirstOrDefault(CustomAttributeData.GetCustomAttributes(thisMemberInfo),
delegate(CustomAttributeData customAttribute) { return customAttribute.Constructor.DeclaringType != null && customAttribute.Constructor.DeclaringType.Name == name; });
}
/// <summary>
/// Get the full name of the type or member, including the namespace name (unlike the FullName property, never returns null).
/// </summary>
public static string GetFullName(MemberInfo thisMemberInfo)
{
if (thisMemberInfo is Type)
{
// The FullName property on Type can return null under certain circumstances, so build the name from the Namespace
// and Name in such a case (but use FullName if possible, because it handles nested types properly).
Type thisType = (Type)thisMemberInfo;
return (thisType.FullName ?? thisType.Namespace + "." + thisType.Name);
}
return (thisMemberInfo.DeclaringType != null ? GetFullName(thisMemberInfo.DeclaringType) + "." : "") + thisMemberInfo.Name;
}
/// <summary>
/// Get the category name (field, method, etc).
/// </summary>
public static string GetCategory(MemberInfo thisMemberInfo)
{
switch (thisMemberInfo.MemberType)
{
case MemberTypes.Field: return "field";
case MemberTypes.Property: return (PropertyInfoUtil.IsIndexed((PropertyInfo)thisMemberInfo) ? "indexer" : "property");
case MemberTypes.Method: return "method";
case MemberTypes.Constructor: return "constructor";
case MemberTypes.Event: return "event";
default: return "type";
}
}
#endregion
}
}