Extensions methods for the C# Type Class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Extensions
{
public static class TypeExtensions
{
/// <summary>
/// Conditionally casts the item into the indicated type using an "as" cast.
/// </summary>
/// <typeparam name="T">The desired type</typeparam>
/// <param name="item">The item.</param>
/// <returns><c>null</c> if the cast failed, otherwise item as T</returns>
public static T As<T>(this object item) where T : class
{
return item as T;
}
/// <summary>
/// Determines whether this instance is a concrete type.
/// </summary>
/// <param name="type">The type to check.</param>
/// <returns>
/// <c>true</c> if the specified type is neither abstract nor an interface; otherwise, <c>false</c>.
/// </returns>
public static bool IsConcrete(this Type type)
{
if (type == null) { return false; }
var typeInfo = type.GetTypeInfo();
return !typeInfo.IsAbstract && !typeInfo.IsInterface;
}
/// <summary>
/// Determines whether this instance is a subclass of Nullable<T>.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>
/// <c>true</c> if the specified type is a subclass of Nullable<T>; otherwise, <c>false</c>.
/// </returns>
public static bool IsNullable(this Type type)
{
var typeInfo = type.GetTypeInfo();
return typeInfo.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
}
/// <summary>
/// Returns the first non-null value from executing the func against the enumerable
/// </summary>
/// <returns><c>null</c> is all values were null.</returns>
public static TReturn FirstValue<TItem, TReturn>(this IEnumerable<TItem> enumerable, Func<TItem, TReturn> func) where TReturn : class
{
foreach (TItem item in enumerable)
{
TReturn @object = func(item);
if (@object != null) { return @object; }
}
return null;
}
/// <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 Create<T>(this Type type, params object[] parameters)
{
var constructor = type.GetConstructor(Flags, null,
parameters != null ? parameters.Select(o => o.GetType()).ToArray() : Type.EmptyTypes, null);
return constructor.Invoke(parameters).CastTo<T>();
}
}
}
// ---------------------------------------------------------------------------
// from Telerik Kendo.Mvc TypeExtensions
// src/Kendo.Mvc/Kendo.Mvc/Extensions/TypeExtensions.cs
// ---------------------------------------------------------------------------
namespace Kendo.Mvc.Extensions
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Reflection;
// using Kendo.Mvc.Resources;
internal static class TypeExtensions
{
internal static readonly Type[] PredefinedTypes =
{
typeof(Object),
typeof(Boolean),
typeof(Char),
typeof(String),
typeof(SByte),
typeof(Byte),
typeof(Int16),
typeof(UInt16),
typeof(Int32),
typeof(UInt32),
typeof(Int64),
typeof(UInt64),
typeof(Single),
typeof(Double),
typeof(Decimal),
typeof(DateTime),
typeof(TimeSpan),
typeof(Guid),
typeof(Math),
typeof(Convert)
};
internal static bool IsPredefinedType(this Type type)
{
foreach (Type t in PredefinedTypes)
{
if (t == type)
{
return true;
}
}
return false;
}
internal static string FirstSortableProperty(this Type type)
{
PropertyInfo firstSortableProperty = type.GetProperties().Where(property => property.PropertyType.IsPredefinedType()
&& !property.PropertyType.IsEnum).FirstOrDefault();
if (firstSortableProperty == null)
{
throw new NotSupportedException("Cannot find a public property of primitive type to sort by.");
}
return firstSortableProperty.Name;
}
internal static bool IsNullableType(this Type type)
{
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
}
internal static Type GetNonNullableType(this Type type)
{
return IsNullableType(type) ? type.GetGenericArguments()[0] : type;
}
internal static string GetTypeName(this Type type)
{
Type baseType = GetNonNullableType(type);
string s = baseType.Name;
if (type != baseType) { s += '?'; }
return s;
}
internal static bool IsNumericType(this Type type)
{
return GetNumericTypeKind(type) != 0;
}
internal static bool IsSignedIntegralType(this Type type)
{
return GetNumericTypeKind(type) == 2;
}
internal static bool IsUnsignedIntegralType(this Type type)
{
return GetNumericTypeKind(type) == 3;
}
internal static int GetNumericTypeKind(this Type type)
{
if (type == null)
{
return 0;
}
type = GetNonNullableType(type);
if (type.IsEnum)
{
return 0;
}
switch (Type.GetTypeCode(type))
{
case TypeCode.Char:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return 1;
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
return 2;
case TypeCode.Byte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return 3;
default:
return 0;
}
}
internal static PropertyInfo GetIndexerPropertyInfo(this Type type, params Type[] indexerArguments)
{
return
(from p in type.GetProperties()
where AreArgumentsApplicable(indexerArguments, p.GetIndexParameters())
select p).FirstOrDefault();
}
private static bool AreArgumentsApplicable(IEnumerable<Type> arguments, IEnumerable<ParameterInfo> parameters)
{
var argumentList = arguments.ToList();
var parameterList = parameters.ToList();
if (argumentList.Count != parameterList.Count)
{
return false;
}
for (int i = 0; i < argumentList.Count; i++)
{
if (parameterList[i].ParameterType != argumentList[i])
{
return false;
}
}
return true;
}
internal static bool IsEnumType(this Type type)
{
return GetNonNullableType(type).IsEnum;
}
internal static bool IsCompatibleWith(this Type source, Type target)
{
if (source == target) { return true; }
if (!target.IsValueType) { return target.IsAssignableFrom(source); }
Type st = source.GetNonNullableType();
Type tt = target.GetNonNullableType();
if (st != source && tt == target) { return false; }
TypeCode sc = st.IsEnum ? TypeCode.Object : Type.GetTypeCode(st);
TypeCode tc = tt.IsEnum ? TypeCode.Object : Type.GetTypeCode(tt);
switch (sc)
{
case TypeCode.SByte:
switch (tc)
{
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
break;
case TypeCode.Byte:
switch (tc)
{
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
break;
case TypeCode.Int16:
switch (tc)
{
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
break;
case TypeCode.UInt16:
switch (tc)
{
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
break;
case TypeCode.Int32:
switch (tc)
{
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
break;
case TypeCode.UInt32:
switch (tc)
{
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
break;
case TypeCode.Int64:
switch (tc)
{
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
break;
case TypeCode.UInt64:
switch (tc)
{
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
}
break;
case TypeCode.Single:
switch (tc)
{
case TypeCode.Single:
case TypeCode.Double:
return true;
}
break;
default:
if (st == tt) { return true; }
break;
}
return false;
}
internal static Type FindGenericType(this Type type, Type genericType)
{
while (type != null && type != typeof(object))
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == genericType) { return type; }
if (genericType.IsInterface)
{
foreach (Type intfType in type.GetInterfaces())
{
Type found = intfType.FindGenericType(genericType);
if (found != null) { return found; }
}
}
type = type.BaseType;
}
return null;
}
internal static string GetName(this Type type)
{
return type.FullName.Replace(type.Namespace + ".", "");
}
internal static object DefaultValue(this Type type)
{
if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
internal static MemberInfo FindPropertyOrField(this Type type, string memberName)
{
MemberInfo memberInfo = type.FindPropertyOrField(memberName, false);
if (memberInfo == null)
{
memberInfo = type.FindPropertyOrField(memberName, true);
}
return memberInfo;
}
internal static MemberInfo FindPropertyOrField(this Type type, string memberName, bool staticAccess)
{
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
(staticAccess ? BindingFlags.Static : BindingFlags.Instance);
foreach (Type t in type.SelfAndBaseTypes())
{
MemberInfo[] members = t.FindMembers(MemberTypes.Property | MemberTypes.Field,
flags, Type.FilterNameIgnoreCase, memberName);
if (members.Length != 0) { return members[0]; }
}
return null;
}
internal static IEnumerable<Type> SelfAndBaseTypes(this Type type)
{
if (type.IsInterface)
{
List<Type> types = new List<Type>();
AddInterface(types, type);
return types;
}
return SelfAndBaseClasses(type);
}
internal static IEnumerable<Type> SelfAndBaseClasses(this Type type)
{
while (type != null)
{
yield return type;
type = type.BaseType;
}
}
static void AddInterface(List<Type> types, Type type)
{
if (!types.Contains(type))
{
types.Add(type);
foreach (Type t in type.GetInterfaces()) AddInterface(types, t);
}
}
internal static bool IsDataRow(this Type type)
{
return type.IsCompatibleWith(typeof(DataRow)) || type.IsCompatibleWith(typeof(DataRowView));
}
internal static bool IsDynamicObject(this Type type)
{
return type == typeof(object) || type.IsCompatibleWith(typeof(System.Dynamic.IDynamicMetaObjectProvider));
}
internal static bool IsDateTime(this Type type)
{
return type == typeof(DateTime) || type == typeof(DateTime?);
}
internal static string ToJavaScriptType(this Type type)
{
if (type == null)
{
return "Object";
}
if (type == typeof(char) || type == typeof(char?))
{
return "String";
}
if (IsNumericType(type))
{
return "Number";
}
if (type == typeof(DateTime) || type == typeof(DateTime?))
{
return "Date";
}
if (type == typeof(string))
{
return "String";
}
if (type == typeof(bool) || type == typeof(bool?))
{
return "Boolean";
}
if (type.GetNonNullableType().IsEnum)
{
return "Number";
}
if (type.GetNonNullableType() == typeof(Guid))
{
return "String";
}
return "Object";
}
internal static bool IsPlainType(this Type type)
{
return !type.IsDynamicObject() && !type.IsDataRow() && !(type.IsCompatibleWith(typeof(ICustomTypeDescriptor)));
}
}
}
// ---------------------------------------------------------------------------
// from SharpSerializer/SharpSerializer/Core/TypeExtensions.cs
// https://github.com/polenter/SharpSerializer/blob/master/SharpSerializer/Core/TypeExtensions.cs
// ---------------------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace System
{
public static class TypeExtensions
{
public static bool IsEnum(this Type type)
{
return type.GetTypeInfo().IsEnum;
}
public static bool IsAssignableFrom(this Type type, Type other)
{
if (other == null)
{
return false;
}
return type.GetTypeInfo().IsAssignableFrom(other.GetTypeInfo());
}
public static bool IsPrimitive(this Type type)
{
return type.GetTypeInfo().IsPrimitive;
}
public static bool IsSubclassOf(this Type type, Type other)
{
return type.GetTypeInfo().IsSubclassOf(other);
}
public static MethodInfo GetMethod(this Type type, string propertyName)
{
return type.GetTypeInfo().GetDeclaredMethod(propertyName);
}
public static PropertyInfo GetProperty(this Type type, string propertyName)
{
return type.GetRuntimeProperty(propertyName);
}
public static PropertyInfo[] GetPublicInstanceProperties(this Type type)
{
var result = type.GetRuntimeProperties().ToArray();
return result;
}
public static Type BaseType(this Type type)
{
return type.GetTypeInfo().BaseType;
}
public static bool IsGenericType(this Type type)
{
return type.GetTypeInfo().IsGenericType;
}
public static Type[] GetGenericArguments(this Type type)
{
return type.GenericTypeArguments;
}
}
}