wasSharp

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 51  →  ?path2? @ 52
/Reflection/Reflection.cs
@@ -0,0 +1,320 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
 
namespace wasSharp
{
public static class Reflection
{
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Retrieves an attribute of type T from an enumeration.
/// </summary>
/// <returns>an attribute of type T</returns>
public static T GetAttributeFromEnumValue<T>(Enum value) where T : Attribute
{
return (T)value.GetType()
.GetRuntimeField(value.ToString())
.GetCustomAttributes(typeof(T), false)
.SingleOrDefault();
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Returns all the attributes of type T of an enumeration.
/// </summary>
/// <typeparam name="T">the attribute to retrieve</typeparam>
/// <returns>a list of attributes</returns>
public static IEnumerable<T> GetEnumAttributes<T>(Enum e) where T : Attribute
{
return e.GetType().GetRuntimeFields().ToArray()
.AsParallel()
.Select(o => GetAttributeFromEnumValue<T>((Enum)o.GetValue(Activator.CreateInstance<T>())));
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Returns all the field names of an enumeration.
/// </summary>
/// <returns>the field names</returns>
public static IEnumerable<string> GetEnumNames<T>()
{
return
typeof(T).GetRuntimeFields().ToArray()
.AsParallel()
.Select(o => o.GetCustomAttribute(typeof(NameAttribute), false))
.Select(o => (o as NameAttribute)?.Name)
.Where(o => !string.IsNullOrEmpty(o))
.Select(o => o);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Returns all the values of an enumeration.
/// </summary>
/// <returns>the values of the enumeration</returns>
public static IEnumerable<T> GetEnumValues<T>()
{
return Enum.GetValues(typeof(T)).Cast<object>().Select(value => (T)value);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get the name from an enumeration value.
/// </summary>
/// <param name="value">an enumeration value</param>
/// <returns>the description or the empty string</returns>
public static string GetNameFromEnumValue(Enum value)
{
var attribute = value.GetType()
.GetRuntimeField(value.ToString())
.GetCustomAttributes(typeof(NameAttribute), false)
.SingleOrDefault() as NameAttribute;
return attribute?.Name;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get the description from an enumeration value.
/// </summary>
/// <param name="value">an enumeration value</param>
/// <returns>the description or the empty string</returns>
public static string GetDescriptionFromEnumValue(Enum value)
{
var attribute = value.GetType()
.GetRuntimeField(value.ToString())
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.SingleOrDefault() as DescriptionAttribute;
return attribute?.Description;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get enumeration value from its name attribute.
/// </summary>
/// <typeparam name="T">the enumeration type</typeparam>
/// <param name="name">the description of a member</param>
/// <param name="comparison">the string comparison to use</param>
/// <returns>the value or the default of T if case no name attribute found</returns>
public static T GetEnumValueFromName<T>(string name,
StringComparison comparison = StringComparison.OrdinalIgnoreCase)
{
var field = typeof(T).GetRuntimeFields().ToArray()
.AsParallel().SelectMany(f => f.GetCustomAttributes(
typeof(NameAttribute), false), (
f, a) => new { Field = f, Att = a })
.SingleOrDefault(a => string.Equals(((NameAttribute)a.Att)
.Name, name, comparison));
return field != null ? (T)field.Field.GetValue(Activator.CreateInstance<T>()) : default(T);
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get the name of a structure member.
/// </summary>
/// <typeparam name="T">the type of the structure to search</typeparam>
/// <param name="structure">the structure to search</param>
/// <param name="item">the value of the item to search</param>
/// <returns>the description or the empty string</returns>
public static string GetStructureMemberName<T>(T structure, object item) where T : struct
{
var f = typeof(T).GetRuntimeFields();
var p = typeof(T).GetRuntimeProperties();
 
if (f != null)
{
var r = f.AsParallel()
.SelectMany(o => o.GetCustomAttributes(typeof(NameAttribute), false),
(o, a) => new { Field = o, Att = a })
.SingleOrDefault(q => q.Field.GetValue(structure).Equals(item));
if (r != null)
return ((NameAttribute)r.Att).Name;
}
 
if (p != null)
{
var r = p.AsParallel()
.SelectMany(o => o.GetCustomAttributes(typeof(NameAttribute), false),
(o, a) => new { Property = o, Att = a })
.SingleOrDefault(q => q.Property.GetValue(structure).Equals(item));
if (r != null)
return ((NameAttribute)r.Att).Name;
}
 
return string.Empty;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get field or property from a class by supplying a path.
/// </summary>
/// <typeparam name="T">the type of the object</typeparam>
/// <param name="o">the object</param>
/// <param name="path">the fully qualified path to the field of property</param>
/// <returns>
/// the last object in the fully qualified path or null in case the field or property could not be found
/// </returns>
public static object GetFP<T>(this T o, string path)
{
if (string.IsNullOrEmpty(path)) return null;
if (o == null) return null;
 
var memberType = o.GetType();
var components = path.Split('.');
 
var f = memberType.GetRuntimeField(components[0]);
var p = memberType.GetRuntimeProperty(components[0]);
 
if (f != null)
return components.Length > 1
? GetFP(f.GetValue(o),
components.Skip(1).Aggregate((a, i) => a + @"." + i))
: memberType.GetRuntimeField(path).GetValue(o);
 
if (p != null)
return components.Length > 1
? GetFP(p.GetValue(o),
components.Skip(1).Aggregate((a, i) => a + @"." + i))
: memberType.GetRuntimeProperty(path).GetValue(o);
 
return null;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Get field or property info from a class by supplying a path.
/// </summary>
/// <typeparam name="T">the type of the object</typeparam>
/// <param name="o">the object</param>
/// <param name="path">the fully qualified path to the field of property</param>
/// <returns>
/// the field or property info of the last object in the path or null if the object cannot be found
/// </returns>
public static object GetFPInfo<T>(this T o, string path)
{
if (string.IsNullOrEmpty(path)) return null;
if (o == null) return null;
 
var memberType = o.GetType();
var components = path.Split('.');
 
var f = memberType.GetRuntimeField(components[0]);
var p = memberType.GetRuntimeProperty(components[0]);
 
if (f != null)
return components.Length > 1
? GetFPInfo(f.GetValue(o),
components.Skip(1).Aggregate((a, i) => a + @"." + i))
: memberType.GetRuntimeField(path);
 
if (p != null)
return components.Length > 1
? GetFPInfo(p.GetValue(o),
components.Skip(1).Aggregate((a, i) => a + @"." + i))
: memberType.GetRuntimeProperty(path);
 
return null;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>Return all the run-time properties for an object.</summary>
/// <param name="o">the object whose properties to return</param>
/// <returns>the property information for all the properties of the object</returns>
public static IEnumerable<PropertyInfo> GetPropertiesInfo<T>(this T o)
{
foreach (var p in o.GetType().GetRuntimeProperties())
yield return p;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>Return all the run-time properties for an object.</summary>
/// <param name="o">the object whose properties to return</param>
/// <returns>the property information for all the properties of the object</returns>
public static IEnumerable<FieldInfo> GetFieldsInfo<T>(this T o)
{
foreach (var p in o.GetType().GetRuntimeFields())
yield return p;
}
 
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Enumerate all the base types recursively starting from a type.
/// </summary>
/// <param name="type">the type</param>
/// <returns>an enumeration of all base types</returns>
public static IEnumerable<Type> GetBaseTypes(this Type type)
{
var baseType = type.GetTypeInfo().BaseType;
if (baseType == null)
yield break;
yield return baseType;
foreach (var t in GetBaseTypes(baseType))
{
yield return t;
}
}
 
/// <summary>
/// A generic name attribute.
/// </summary>
public class NameAttribute : Attribute
{
protected readonly string name;
 
public NameAttribute(string name)
{
this.name = name;
}
 
public string Name => name;
}
 
/// <summary>
/// A generic description attribute.
/// </summary>
public class DescriptionAttribute : Attribute
{
protected readonly string description;
 
public DescriptionAttribute(string description)
{
this.description = description;
}
 
public string Description => description;
}
}
}