TypeHelper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / System.Runtime.DurableInstancing / System / Runtime / TypeHelper.cs / 1305376 / TypeHelper.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.Runtime 
{
    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel;
    using System.Diagnostics.CodeAnalysis; 

    static class TypeHelper
    {
        public static readonly Type ArrayType = typeof(Array); 
        public static readonly Type BoolType = typeof(bool);
        public static readonly Type GenericCollectionType = typeof(ICollection<>); 
        public static readonly Type ByteType = typeof(byte); 
        public static readonly Type SByteType = typeof(sbyte);
        public static readonly Type CharType = typeof(char); 
        public static readonly Type ShortType = typeof(short);
        public static readonly Type UShortType = typeof(ushort);
        public static readonly Type IntType = typeof(int);
        public static readonly Type UIntType = typeof(uint); 
        public static readonly Type LongType = typeof(long);
        public static readonly Type ULongType = typeof(ulong); 
        public static readonly Type FloatType = typeof(float); 
        public static readonly Type DoubleType = typeof(double);
        public static readonly Type DecimalType = typeof(decimal); 
        public static readonly Type ExceptionType = typeof(Exception);
        public static readonly Type NullableType = typeof(Nullable<>);
        public static readonly Type ObjectType = typeof(object);
        public static readonly Type StringType = typeof(string); 
        public static readonly Type TypeType = typeof(Type);
        public static readonly Type VoidType = typeof(void); 
 
        public static bool AreTypesCompatible(object source, Type destinationType)
        { 
            if (source == null)
            {
                return !destinationType.IsValueType || IsNullableType(destinationType);
            } 

            return AreTypesCompatible(source.GetType(), destinationType); 
        } 

        // return true if the sourceType is implicitly convertible to the destinationType 
        public static bool AreTypesCompatible(Type sourceType, Type destinationType)
        {
            if (object.ReferenceEquals(sourceType, destinationType))
            { 
                return true;
            } 
 
            return IsImplicitNumericConversion(sourceType, destinationType) ||
                IsImplicitReferenceConversion(sourceType, destinationType) || 
                IsImplicitBoxingConversion(sourceType, destinationType) ||
                IsImplicitNullableConversion(sourceType, destinationType);
        }
 
        // simpler, more performant version of AreTypesCompatible when
        // we know both sides are reference types 
        public static bool AreReferenceTypesCompatible(Type sourceType, Type destinationType) 
        {
            Fx.Assert(!sourceType.IsValueType && !destinationType.IsValueType, "AreReferenceTypesCompatible can only be used for reference types"); 
            if (object.ReferenceEquals(sourceType, destinationType))
            {
                return true;
            } 

            return IsImplicitReferenceConversion(sourceType, destinationType); 
        } 

        // variation to OfType that uses AreTypesCompatible instead of Type equality 
        public static IEnumerable GetCompatibleTypes(IEnumerable enumerable, Type targetType)
        {
            foreach (Type sourceType in enumerable)
            { 
                if (TypeHelper.AreTypesCompatible(sourceType, targetType))
                { 
                    yield return sourceType; 
                }
            } 
        }

        public static bool ContainsCompatibleType(IEnumerable enumerable, Type targetType)
        { 
            foreach (Type sourceType in enumerable)
            { 
                if (TypeHelper.AreTypesCompatible(sourceType, targetType)) 
                {
                    return true; 
                }
            }

            return false; 
        }
 
        // handles not only the simple cast, but also value type widening, etc. 
        public static T Convert(object source)
        { 
            // first check the common cases
            if (source is T)
            {
                return (T)source; 
            }
 
            if (source == null) 
            {
                if (typeof(T).IsValueType && !IsNullableType(typeof(T))) 
                {
                    throw Fx.Exception.AsError(new InvalidCastException(SRCore.CannotConvertObject(source, typeof(T))));
                }
 
                return default(T);
            } 
 
            T result;
            if (TryNumericConversion(source, out result)) 
            {
                return result;
            }
 
            throw Fx.Exception.AsError(new InvalidCastException(SRCore.CannotConvertObject(source, typeof(T))));
        } 
 
        // get all of the types that this Type implements (based classes, interfaces, etc)
        public static IEnumerable GetImplementedTypes(Type type) 
        {
            HashSet typesEncountered = new HashSet();

            GetImplementedTypesHelper(type, typesEncountered); 
            return typesEncountered;
        } 
 
        static void GetImplementedTypesHelper(Type type, HashSet typesEncountered)
        { 
            if (typesEncountered.Contains(type))
            {
                return;
            } 

            typesEncountered.Add(type); 
 
            Type[] interfaces = type.GetInterfaces();
            for (int i = 0; i < interfaces.Length; ++i) 
            {
                GetImplementedTypesHelper(interfaces[i], typesEncountered);
            }
 
            Type baseType = type.BaseType;
            while ((baseType != null) && (baseType != TypeHelper.ObjectType)) 
            { 
                GetImplementedTypesHelper(baseType, typesEncountered);
                baseType = baseType.BaseType; 
            }
        }

        [SuppressMessage(FxCop.Category.Maintainability, FxCop.Rule.AvoidExcessiveComplexity, 
            Justification = "Need to check all possible numeric conversions")]
        static bool IsImplicitNumericConversion(Type source, Type destination) 
        { 
            TypeCode sourceTypeCode = Type.GetTypeCode(source);
            TypeCode destinationTypeCode = Type.GetTypeCode(destination); 

            switch (sourceTypeCode)
            {
                case TypeCode.SByte: 
                    switch (destinationTypeCode)
                    { 
                        case TypeCode.Int16: 
                        case TypeCode.Int32:
                        case TypeCode.Int64: 
                        case TypeCode.Single:
                        case TypeCode.Double:
                        case TypeCode.Decimal:
                            return true; 
                    }
                    return false; 
                case TypeCode.Byte: 
                    switch (destinationTypeCode)
                    { 
                        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;
                    }
                    return false;
                case TypeCode.Int16: 
                    switch (destinationTypeCode)
                    { 
                        case TypeCode.Int32: 
                        case TypeCode.Int64:
                        case TypeCode.Single: 
                        case TypeCode.Double:
                        case TypeCode.Decimal:
                            return true;
                    } 
                    return false;
                case TypeCode.UInt16: 
                    switch (destinationTypeCode) 
                    {
                        case TypeCode.Int32: 
                        case TypeCode.UInt32:
                        case TypeCode.Int64:
                        case TypeCode.UInt64:
                        case TypeCode.Single: 
                        case TypeCode.Double:
                        case TypeCode.Decimal: 
                            return true; 
                    }
                    return false; 
                case TypeCode.Int32:
                    switch (destinationTypeCode)
                    {
                        case TypeCode.Int64: 
                        case TypeCode.Single:
                        case TypeCode.Double: 
                        case TypeCode.Decimal: 
                            return true;
                    } 
                    return false;
                case TypeCode.UInt32:
                    switch (destinationTypeCode)
                    { 
                        case TypeCode.UInt32:
                        case TypeCode.Int64: 
                        case TypeCode.UInt64: 
                        case TypeCode.Single:
                        case TypeCode.Double: 
                        case TypeCode.Decimal:
                            return true;
                    }
                    return false; 
                case TypeCode.Int64:
                case TypeCode.UInt64: 
                    switch (destinationTypeCode) 
                    {
                        case TypeCode.Single: 
                        case TypeCode.Double:
                        case TypeCode.Decimal:
                            return true;
                    } 
                    return false;
                case TypeCode.Char: 
                    switch (destinationTypeCode) 
                    {
                        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;
                    } 
                    return false;
                case TypeCode.Single:
                    return (destinationTypeCode == TypeCode.Double);
            } 

            return false; 
        } 

        static bool IsImplicitReferenceConversion(Type sourceType, Type destinationType) 
        {
            return destinationType.IsAssignableFrom(sourceType);
        }
 
        static bool IsImplicitBoxingConversion(Type sourceType, Type destinationType)
        { 
            if (sourceType.IsValueType && (destinationType == ObjectType || destinationType == typeof(ValueType))) 
            {
                return true; 
            }
            if (sourceType.IsEnum && destinationType == typeof(Enum))
            {
                return true; 
            }
            return false; 
        } 

        static bool IsImplicitNullableConversion(Type sourceType, Type destinationType) 
        {
            if (!IsNullableType(destinationType))
            {
                return false; 
            }
 
            destinationType = destinationType.GetGenericArguments()[0]; 
            if (IsNullableType(sourceType))
            { 
                sourceType = sourceType.GetGenericArguments()[0];
            }
            return AreTypesCompatible(sourceType, destinationType);
        } 

        static bool IsNullableType(Type type) 
        { 
            return type.IsGenericType && type.GetGenericTypeDefinition() == NullableType;
        } 

        static bool TryNumericConversion(object source, out T result)
        {
            Fx.Assert(source != null, "caller must verify"); 
            TypeCode sourceTypeCode = Type.GetTypeCode(source.GetType());
            TypeCode destinationTypeCode = Type.GetTypeCode(typeof(T)); 
 
            switch (sourceTypeCode)
            { 
                case TypeCode.SByte:
                    {
                        SByte sbyteSource = (SByte)source;
                        switch (destinationTypeCode) 
                        {
                            case TypeCode.Int16: 
                                result = (T)(object)(Int16)sbyteSource; 
                                return true;
                            case TypeCode.Int32: 
                                result = (T)(object)(Int32)sbyteSource;
                                return true;
                            case TypeCode.Int64:
                                result = (T)(object)(Int64)sbyteSource; 
                                return true;
                            case TypeCode.Single: 
                                result = (T)(object)(Single)sbyteSource; 
                                return true;
                            case TypeCode.Double: 
                                result = (T)(object)(Double)sbyteSource;
                                return true;
                            case TypeCode.Decimal:
                                result = (T)(object)(Decimal)sbyteSource; 
                                return true;
                        } 
                        break; 
                    }
                case TypeCode.Byte: 
                    {
                        Byte byteSource = (Byte)source;
                        switch (destinationTypeCode)
                        { 
                            case TypeCode.Int16:
                                result = (T)(object)(Int16)byteSource; 
                                return true; 
                            case TypeCode.UInt16:
                                result = (T)(object)(UInt16)byteSource; 
                                return true;
                            case TypeCode.Int32:
                                result = (T)(object)(Int32)byteSource;
                                return true; 
                            case TypeCode.UInt32:
                                result = (T)(object)(UInt32)byteSource; 
                                return true; 
                            case TypeCode.Int64:
                                result = (T)(object)(Int64)byteSource; 
                                return true;
                            case TypeCode.UInt64:
                                result = (T)(object)(UInt64)byteSource;
                                return true; 
                            case TypeCode.Single:
                                result = (T)(object)(Single)byteSource; 
                                return true; 
                            case TypeCode.Double:
                                result = (T)(object)(Double)byteSource; 
                                return true;
                            case TypeCode.Decimal:
                                result = (T)(object)(Decimal)byteSource;
                                return true; 
                        }
                        break; 
                    } 
                case TypeCode.Int16:
                    { 
                        Int16 int16Source = (Int16)source;
                        switch (destinationTypeCode)
                        {
                            case TypeCode.Int32: 
                                result = (T)(object)(Int32)int16Source;
                                return true; 
                            case TypeCode.Int64: 
                                result = (T)(object)(Int64)int16Source;
                                return true; 
                            case TypeCode.Single:
                                result = (T)(object)(Single)int16Source;
                                return true;
                            case TypeCode.Double: 
                                result = (T)(object)(Double)int16Source;
                                return true; 
                            case TypeCode.Decimal: 
                                result = (T)(object)(Decimal)int16Source;
                                return true; 
                        }
                        break;
                    }
                case TypeCode.UInt16: 
                    {
                        UInt16 uint16Source = (UInt16)source; 
                        switch (destinationTypeCode) 
                        {
                            case TypeCode.Int32: 
                                result = (T)(object)(Int32)uint16Source;
                                return true;
                            case TypeCode.UInt32:
                                result = (T)(object)(UInt32)uint16Source; 
                                return true;
                            case TypeCode.Int64: 
                                result = (T)(object)(Int64)uint16Source; 
                                return true;
                            case TypeCode.UInt64: 
                                result = (T)(object)(UInt64)uint16Source;
                                return true;
                            case TypeCode.Single:
                                result = (T)(object)(Single)uint16Source; 
                                return true;
                            case TypeCode.Double: 
                                result = (T)(object)(Double)uint16Source; 
                                return true;
                            case TypeCode.Decimal: 
                                result = (T)(object)(Decimal)uint16Source;
                                return true;
                        }
                        break; 
                    }
                case TypeCode.Int32: 
                    { 
                        Int32 int32Source = (Int32)source;
                        switch (destinationTypeCode) 
                        {
                            case TypeCode.Int64:
                                result = (T)(object)(Int64)int32Source;
                                return true; 
                            case TypeCode.Single:
                                result = (T)(object)(Single)int32Source; 
                                return true; 
                            case TypeCode.Double:
                                result = (T)(object)(Double)int32Source; 
                                return true;
                            case TypeCode.Decimal:
                                result = (T)(object)(Decimal)int32Source;
                                return true; 
                        }
                        break; 
                    } 
                case TypeCode.UInt32:
                    { 
                        UInt32 uint32Source = (UInt32)source;
                        switch (destinationTypeCode)
                        {
                            case TypeCode.UInt32: 
                                result = (T)(object)(UInt32)uint32Source;
                                return true; 
                            case TypeCode.Int64: 
                                result = (T)(object)(Int64)uint32Source;
                                return true; 
                            case TypeCode.UInt64:
                                result = (T)(object)(UInt64)uint32Source;
                                return true;
                            case TypeCode.Single: 
                                result = (T)(object)(Single)uint32Source;
                                return true; 
                            case TypeCode.Double: 
                                result = (T)(object)(Double)uint32Source;
                                return true; 
                            case TypeCode.Decimal:
                                result = (T)(object)(Decimal)uint32Source;
                                return true;
                        } 
                        break;
                    } 
                case TypeCode.Int64: 
                    {
                        Int64 int64Source = (Int64)source; 
                        switch (destinationTypeCode)
                        {
                            case TypeCode.Single:
                                result = (T)(object)(Single)int64Source; 
                                return true;
                            case TypeCode.Double: 
                                result = (T)(object)(Double)int64Source; 
                                return true;
                            case TypeCode.Decimal: 
                                result = (T)(object)(Decimal)int64Source;
                                return true;
                        }
                        break; 
                    }
                case TypeCode.UInt64: 
                    { 
                        UInt64 uint64Source = (UInt64)source;
                        switch (destinationTypeCode) 
                        {
                            case TypeCode.Single:
                                result = (T)(object)(Single)uint64Source;
                                return true; 
                            case TypeCode.Double:
                                result = (T)(object)(Double)uint64Source; 
                                return true; 
                            case TypeCode.Decimal:
                                result = (T)(object)(Decimal)uint64Source; 
                                return true;
                        }
                        break;
                    } 
                case TypeCode.Char:
                    { 
                        Char charSource = (Char)source; 
                        switch (destinationTypeCode)
                        { 
                            case TypeCode.UInt16:
                                result = (T)(object)(UInt16)charSource;
                                return true;
                            case TypeCode.Int32: 
                                result = (T)(object)(Int32)charSource;
                                return true; 
                            case TypeCode.UInt32: 
                                result = (T)(object)(UInt32)charSource;
                                return true; 
                            case TypeCode.Int64:
                                result = (T)(object)(Int64)charSource;
                                return true;
                            case TypeCode.UInt64: 
                                result = (T)(object)(UInt64)charSource;
                                return true; 
                            case TypeCode.Single: 
                                result = (T)(object)(Single)charSource;
                                return true; 
                            case TypeCode.Double:
                                result = (T)(object)(Double)charSource;
                                return true;
                            case TypeCode.Decimal: 
                                result = (T)(object)(Decimal)charSource;
                                return true; 
                        } 
                        break;
                    } 
                case TypeCode.Single:
                    {
                        if (destinationTypeCode == TypeCode.Double)
                        { 
                            result = (T)(object)(Double)(Single)source;
                            return true; 
                        } 
                        break;
                    } 
            }

            result = default(T);
            return false; 
        }
 
        public static object GetDefaultValueForType(Type type) 
        {
            if (!type.IsValueType) 
            {
                return null;
            }
 
            if (type.IsEnum)
            { 
                Array enumValues = Enum.GetValues(type); 
                if (enumValues.Length > 0)
                { 
                    return enumValues.GetValue(0);
                }
            }
 
            return Activator.CreateInstance(type);
        } 
 
        public static bool IsNullableValueType(Type type)
        { 
            return type.IsValueType && IsNullableType(type);
        }

        public static bool IsNonNullableValueType(Type type) 
        {
            if (!type.IsValueType) 
            { 
                return false;
            } 

            if (type.IsGenericType)
            {
                return false; 
            }
 
            return type != StringType; 
        }
 
        public static bool ShouldFilterProperty(PropertyDescriptor property, Attribute[] attributes)
        {
            if (attributes == null || attributes.Length == 0)
            { 
                return false;
            } 
 
            for (int i = 0; i < attributes.Length; i++)
            { 
                Attribute filterAttribute = attributes[i];
                Attribute propertyAttribute = property.Attributes[filterAttribute.GetType()];
                if (propertyAttribute == null)
                { 
                    if (!filterAttribute.IsDefaultAttribute())
                    { 
                        return true; 
                    }
                } 
                else
                {
                    if (!filterAttribute.Match(propertyAttribute))
                    { 
                        return true;
                    } 
                } 
            }
            return false; 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK