/Fasterflect/Fasterflect/Extensions/Core/TypeExtensions.cs
C# | 223 lines | 137 code | 14 blank | 72 comment | 44 complexity | 6152eec5acdd59d0c47a3cedc997078d MD5 | raw file
- #region License
- // Copyright 2010 Buu Nguyen, Morten Mertner
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- // The latest version of this file can be found at http://fasterflect.codeplex.com/
- #endregion
-
- using System;
- using System.Linq;
- using System.Collections.Generic;
-
- namespace Fasterflect
- {
- /// <summary>
- /// Extension methods for inspecting types.
- /// </summary>
- public static class TypeExtensions
- {
- #region Implements
- /// <summary>
- /// Returns true if the supplied <paramref name="type"/> implements the given interface <typeparamref name="T"/>.
- /// </summary>
- /// <typeparam name="T">The type (interface) to check for.</typeparam>
- /// <param name="type">The type to check.</param>
- /// <returns>True if the given type implements the specified interface.</returns>
- /// <remarks>This method is for interfaces only. Use <seealso cref="Inherits"/> for class types and <seealso cref="InheritsOrImplements"/>
- /// to check both interfaces and classes.</remarks>
- public static bool Implements<T>( this Type type )
- {
- return type.Implements( typeof(T) );
- }
-
- /// <summary>
- /// Returns true of the supplied <paramref name="type"/> implements the given interface <paramref name="interfaceType"/>. If the given
- /// interface type is a generic type definition this method will use the generic type definition of any implemented interfaces
- /// to determine the result.
- /// </summary>
- /// <param name="interfaceType">The interface type to check for.</param>
- /// <param name="type">The type to check.</param>
- /// <returns>True if the given type implements the specified interface.</returns>
- /// <remarks>This method is for interfaces only. Use <seealso cref="Inherits"/> for classes and <seealso cref="InheritsOrImplements"/>
- /// to check both interfaces and classes.</remarks>
- public static bool Implements( this Type type, Type interfaceType )
- {
- if( type == null || interfaceType == null || type == interfaceType )
- return false;
- if( interfaceType.IsGenericTypeDefinition && type.GetInterfaces().Where( t => t.IsGenericType ).Select( t => t.GetGenericTypeDefinition() ).Any( gt => gt == interfaceType ) )
- {
- return true;
- }
- return interfaceType.IsAssignableFrom( type );
- }
- #endregion
-
- #region Inherits
- /// <summary>
- /// Returns true if the supplied <paramref name="type"/> inherits from the given class <typeparamref name="T"/>.
- /// </summary>
- /// <typeparam name="T">The type (class) to check for.</typeparam>
- /// <param name="type">The type to check.</param>
- /// <returns>True if the given type inherits from the specified class.</returns>
- /// <remarks>This method is for classes only. Use <seealso cref="Implements"/> for interface types and <seealso cref="InheritsOrImplements"/>
- /// to check both interfaces and classes.</remarks>
- public static bool Inherits<T>( this Type type )
- {
- return type.Inherits( typeof(T) );
- }
-
- /// <summary>
- /// Returns true if the supplied <paramref name="type"/> inherits from the given class <paramref name="baseType"/>.
- /// </summary>
- /// <param name="baseType">The type (class) to check for.</param>
- /// <param name="type">The type to check.</param>
- /// <returns>True if the given type inherits from the specified class.</returns>
- /// <remarks>This method is for classes only. Use <seealso cref="Implements"/> for interface types and <seealso cref="InheritsOrImplements"/>
- /// to check both interfaces and classes.</remarks>
- public static bool Inherits( this Type type, Type baseType )
- {
- if( baseType == null || type == null || type == baseType )
- return false;
- var rootType = typeof(object);
- if( baseType == rootType )
- return true;
- while( type != null && type != rootType )
- {
- var current = type.IsGenericType && baseType.IsGenericTypeDefinition ? type.GetGenericTypeDefinition() : type;
- if( baseType == current )
- return true;
- type = type.BaseType;
- }
- return false;
- }
- #endregion
-
- #region InheritsOrImplements
- /// <summary>
- /// Returns true if the supplied <paramref name="type"/> inherits from or implements the type <typeparamref name="T"/>.
- /// </summary>
- /// <typeparam name="T">The base type to check for.</typeparam>
- /// <param name="type">The type to check.</param>
- /// <returns>True if the given type inherits from or implements the specified base type.</returns>
- public static bool InheritsOrImplements<T>( this Type type )
- {
- return type.InheritsOrImplements( typeof(T) );
- }
-
- /// <summary>
- /// Returns true of the supplied <paramref name="type"/> inherits from or implements the type <paramref name="baseType"/>.
- /// </summary>
- /// <param name="baseType">The base type to check for.</param>
- /// <param name="type">The type to check.</param>
- /// <returns>True if the given type inherits from or implements the specified base type.</returns>
- public static bool InheritsOrImplements( this Type type, Type baseType )
- {
- if( type == null || baseType == null )
- return false;
- return baseType.IsInterface ? type.Implements( baseType ) : type.Inherits( baseType );
- }
- #endregion
-
- #region IsFrameworkType
-
- #region IsFrameworkType Helpers
- private static readonly List<byte[]> tokens = new List<byte[]>
- {
- new byte[] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 },
- new byte[] { 0x31, 0xbf, 0x38, 0x56, 0xad, 0x36, 0x4e, 0x35 },
- new byte[] { 0xb0, 0x3f, 0x5f, 0x7f, 0x11, 0xd5, 0x0a, 0x3a }
- };
-
- internal class ByteArrayEqualityComparer : EqualityComparer<byte[]>
- {
- public override bool Equals( byte[] x, byte[] y )
- {
- return x != null && y != null && x.SequenceEqual( y );
- }
-
- public override int GetHashCode( byte[] obj )
- {
- return obj.GetHashCode();
- }
- }
- #endregion
-
- /// <summary>
- /// Returns true if the supplied type is defined in an assembly signed by Microsoft.
- /// </summary>
- public static bool IsFrameworkType( this Type type )
- {
- if( type == null )
- {
- throw new ArgumentNullException( "type" );
- }
- byte[] publicKeyToken = type.Assembly.GetName().GetPublicKeyToken();
- return publicKeyToken != null && tokens.Contains( publicKeyToken, new ByteArrayEqualityComparer() );
- }
- #endregion
-
- #region Name (with generic pretty-printing)
- /// <summary>
- /// Returns the C# name, including any generic parameters, of the supplied <paramref name="type"/>.
- /// </summary>
- /// <param name="type">The type to return the name for.</param>
- /// <returns>The type name formatted as you'd write it in C#.</returns>
- public static string Name( this Type type )
- {
- if( type.IsArray )
- {
- return string.Format( "{0}[]", type.GetElementType().Name() );
- }
- if( type.ContainsGenericParameters || type.IsGenericType )
- {
- if( type.BaseType == typeof(Nullable<>) || (type.BaseType == typeof(ValueType) && type.UnderlyingSystemType.Name.StartsWith( "Nullable" )) )
- {
- return GetCSharpTypeName( type.GetGenericArguments().Single().Name ) + "?";
- }
- int index = type.Name.IndexOf( "`" );
- string genericTypeName = index > 0 ? type.Name.Substring( 0, index ) : type.Name;
- string genericArgs = string.Join( ",", type.GetGenericArguments().Select( t => t.Name() ).ToArray() );
- return genericArgs.Length == 0 ? genericTypeName : genericTypeName + "<" + genericArgs + ">";
- }
- return GetCSharpTypeName( type.Name );
- }
-
- private static string GetCSharpTypeName( string typeName )
- {
- switch( typeName )
- {
- case "String":
- case "Object":
- case "Void":
- case "Byte":
- case "Double":
- case "Decimal":
- return typeName.ToLower();
- case "Int16":
- return "short";
- case "Int32":
- return "int";
- case "Int64":
- return "long";
- case "Single":
- return "float";
- case "Boolean":
- return "bool";
- default:
- return typeName;
- }
- }
- #endregion
- }
- }