Extension methods for the C# object class.
using System;
using System.Text;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
public static class ObjectExtensions
{
/// <summary>
/// Uses reflection to output a string dump of all the object's properties
/// and values in a nice readable format. Should only be used for
/// debug/error dumps as performance of reflection is obviously a concern.
/// </summary>
/// <param name="instance">Object instance to dump info for.</param>
/// <returns>Formatted friendly string of object information.</returns>
public static string ToStringDump(this object instance)
{
var flags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
var propInfos = instance.GetType().GetProperties(flags);
var sb = new StringBuilder();
string typeName = instance.GetType().Name;
sb.AppendLine(typeName);
sb.AppendLine("".PadRight(typeName.Length + 5, '='));
foreach (System.Reflection.PropertyInfo propInfo in propInfos)
{
sb.Append(propInfo.Name);
sb.Append(": ");
if (propInfo.GetIndexParameters().Length > 0)
{
sb.Append("Indexed Property cannot be used");
}
else
{
object value = propInfo.GetValue(instance, null);
sb.Append(value != null ? value : "null");
}
sb.Append(System.Environment.NewLine);
}
return sb.ToString();
}
/// <remarks>https://github.com/madhatter22/LinqToLdap/blob/master/LinqToLdap.Tests/TestSupport/ExtensionMethods/ObjectExtensions.cs</remarks>
private const BindingFlags Flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
/// <remarks>https://github.com/madhatter22/LinqToLdap/blob/master/LinqToLdap.Tests/TestSupport/ExtensionMethods/ObjectExtensions.cs</remarks>
public static T As<T>(this object obj) where T : class
{
return obj as T;
}
/// <remarks>https://github.com/madhatter22/LinqToLdap/blob/master/LinqToLdap.Tests/TestSupport/ExtensionMethods/ObjectExtensions.cs</remarks>
public static T CastTo<T>(this object obj)
{
return (T)obj;
}
/// <remarks>https://github.com/madhatter22/LinqToLdap/blob/master/LinqToLdap.Tests/TestSupport/ExtensionMethods/ObjectExtensions.cs</remarks>
public static object Call(this object obj, string methodName, params object[] parameters)
{
var type = obj.GetType();
var method = type.GetMethod(methodName, Flags, null, parameters == null ? Type.EmptyTypes : parameters.Select(p => p.GetType()).ToArray(), null);
return method.Invoke(obj, parameters);
}
/// <summary>
/// Returns a field given the name and the type of object.
/// </summary>
/// <param name="fieldName">The name of the field</param>
/// <param name="objectType">The type of object to which the field belongs</param>
/// <returns>The field</returns>
/// <remarks>https://github.com/madhatter22/LinqToLdap/blob/master/LinqToLdap.Tests/TestSupport/ExtensionMethods/ObjectExtensions.cs</remarks>
private static FieldInfo GetField(string fieldName, Type objectType)
{
FieldInfo field = objectType.GetField(fieldName, Flags);
if (field == null)
{
Type baseType = objectType.BaseType;
while (baseType != typeof(object))
{
field = GetField(fieldName, baseType);
if (field != null)
{
break;
}
baseType = baseType.BaseType;
}
}
return field;
}
/// <summary>
/// Returns a property given the name and the type of object.
/// </summary>
/// <param name="propertyName">The name of the property</param>
/// <param name="objectType">The type of object to which the property belongs</param>
/// <returns>The property</returns>
/// <remarks>https://github.com/madhatter22/LinqToLdap/blob/master/LinqToLdap.Tests/TestSupport/ExtensionMethods/ObjectExtensions.cs</remarks>
private static PropertyInfo GetProperty(string propertyName, Type objectType)
{
PropertyInfo property = objectType.GetProperty(propertyName, Flags);
if (property == null)
{
Type baseType = objectType.BaseType;
while (baseType != typeof(object))
{
property = GetProperty(propertyName, baseType);
if (property != null)
{
break;
}
baseType = baseType.BaseType;
}
}
return property;
}
/// <summary>
/// Gets the value of a field for an object.
/// </summary>
/// <typeparam name="TProperty">The type of the field to look for.</typeparam>
/// <param name="propertyName">The name of the field.</param>
/// <param name="source">>The object to which the field belongs</param>
/// <returns>The value of the field</returns>
/// <remarks>https://github.com/madhatter22/LinqToLdap/blob/master/LinqToLdap.Tests/TestSupport/ExtensionMethods/ObjectExtensions.cs</remarks>
public static TProperty PropertyValue<TProperty>(this object source, string propertyName)
{
PropertyInfo property = GetProperty(propertyName, source.GetType());
return (TProperty)property.GetValue(source, Flags, null, null, null);
}
/// <summary>
/// Sets the value of a property for an object.
/// </summary>
/// <typeparam name="TProperty">The type of the property to look for.</typeparam>
/// <param name="propertyName">The name of the property.</param>
/// <param name="source">>The object to which the property belongs</param>
/// <param name="value">The value to which the property will be set.</param>
/// <remarks>https://github.com/madhatter22/LinqToLdap/blob/master/LinqToLdap.Tests/TestSupport/ExtensionMethods/ObjectExtensions.cs</remarks>
public static void SetPropertyValue<TProperty>(this object source, string propertyName, TProperty value)
{
PropertyInfo property = GetProperty(propertyName, source.GetType());
property.SetValue(source, value, Flags, null, null, null);
}
/// <summary>
/// Gets the value of a field for an object.
/// </summary>
/// <typeparam name="TField">The type of the field to look for.</typeparam>
/// <param name="fieldName">The name of the field.</param>
/// <param name="source">>The object to which the field belongs</param>
/// <returns>The value of the field</returns>
/// <remarks>https://github.com/madhatter22/LinqToLdap/blob/master/LinqToLdap.Tests/TestSupport/ExtensionMethods/ObjectExtensions.cs</remarks>
public static TField FieldValueEx<TField>(this object source, string fieldName)
{
FieldInfo field = GetField(fieldName, source.GetType());
return (TField)field.GetValue(source);
}
/// <summary>
/// Gets the value of a field for an object.
/// </summary>
/// <typeparam name="TField">The type of the field to look for.</typeparam>
/// <param name="fieldName">The name of the field.</param>
/// <param name="source">>The object to which the field belongs</param>
/// <param name="value">The value to which the field will be set.</param>
/// <remarks>https://github.com/madhatter22/LinqToLdap/blob/master/LinqToLdap.Tests/TestSupport/ExtensionMethods/ObjectExtensions.cs</remarks>
public static void SetFieldValue<TField>(this object source, string fieldName, TField value)
{
FieldInfo field = GetField(fieldName, source.GetType());
field.SetValue(source, value);
}
/// <summary>
/// Transforms the values of the object into a dictionary of strings.
/// </summary>
/// <param name="values">The object instance to convert.</param>
/// <returns>A dictionary mapping field names to values.</returns>
/// <remarks>https://github.com/AngleSharp/AngleSharp/blob/master/src/AngleSharp/Common/ObjectExtensions.cs#L18</remarks>
public static Dictionary<string, string> ToDictionary(this object values)
{
var symbols = new Dictionary<string, string>();
if (values != null)
{
var properties = values.GetType().GetProperties();
foreach (var property in properties)
{
var value = property.GetValue(values, null) ?? string.Empty;
symbols.Add(property.Name, value.ToString());
}
}
return symbols;
}
/// <summary>
/// Tries to obtain the given key, otherwise returns the default value.
/// </summary>
/// <typeparam name="T">The struct type.</typeparam>
/// <param name="values">The dictionary for the lookup.</param>
/// <param name="key">The key to look for.</param>
/// <returns>A nullable struct type.</returns>
/// <remarks>https://github.com/AngleSharp/AngleSharp/blob/master/src/AngleSharp/Common/ObjectExtensions.cs#L106</remarks>
public static T? TryGet<T>(this IDictionary<string, object> values, string key)
where T : struct
{
if (values.TryGetValue(key, out var value) && value is T result)
{
return result;
}
return null;
}
/// <summary>
/// Tries to obtain the given key, otherwise returns null.
/// </summary>
/// <param name="values">The dictionary for the lookup.</param>
/// <param name="key">The key to look for.</param>
/// <returns>An object instance or null.</returns>
/// <remarks>https://github.com/AngleSharp/AngleSharp/blob/master/src/AngleSharp/Common/ObjectExtensions.cs#L123</remarks>
public static object TryGet(this IDictionary<string, object> values, string key)
{
values.TryGetValue(key, out var value);
return value;
}
/// <summary>
/// Gets the value of the given key, otherwise the provided default
/// value.
/// </summary>
/// <typeparam name="T">The type of the keys.</typeparam>
/// <typeparam name="TU">The type of the value.</typeparam>
/// <param name="values">The dictionary for the lookup.</param>
/// <param name="key">The key to look for.</param>
/// <param name="defaultValue">The provided fallback value.</param>
/// <returns>The value or the provided fallback.</returns>
/// <remarks>https://github.com/AngleSharp/AngleSharp/blob/master/src/AngleSharp/Common/ObjectExtensions.cs#L139</remarks>
public static TU GetOrDefault<T, TU>(this IDictionary<T, TU> values, T key, TU defaultValue)
{
return values.TryGetValue(key, out var value) ? value : defaultValue;
}
}