csharp/1996v/Bssom.Net/Bssom.Serializer/Internal/TypeUtils.cs

TypeUtils.cs
//using System.Runtime.CompilerServices;

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace Bssom.Serializer.Internal
{
    internal static clast TypeUtils
    {
        public static IEnumerable GetGetEnumerator(this IDictionary value)
        {
            foreach (DictionaryEntry item in value)
            {
                yield return new KeyValuePair(item.Key, item.Value);
            }
        }

        public static IEnumerable ToIEnumerable(this NameValueCollection value)
        {
            foreach (object item in value)
            {
                yield return new KeyValuePair((string)item, value[(string)item]);
            }
        }
        public static IEnumerable ToIEnumerable(this StringDictionary value)
        {
            foreach (DictionaryEntry item in value)
            {
                yield return new KeyValuePair((string)item.Key, (string)item.Value);
            }
        }

        public static IEnumerable ToIEnumerable(this DataRow value)
        {
            foreach (DataColumn column in value.Table.Columns)
            {
                yield return new KeyValuePair(column.ColumnName, value[column]);
            }
        }

        public static int GetIDictionaryCount(this IEnumerable value)
        {
            DEBUG.astert(value is IDictionary || value is IReadOnlyDictionary);

            if (value is IDictionary idic)
            {
                return idic.Count;
            }
            else
            {
                return ((IReadOnlyDictionary)value).Count;
            }
        }
        public static bool TryGetICollectionCount(this IEnumerable value, out int count)
        {
            if (value is ICollection idic)
            {
                count = idic.Count;
                return true;
            }
            else if (value is IReadOnlyCollection irdic)
            {
                count = irdic.Count;
                return true;
            }

            count = 0;
            return false;
        }

        public static bool TryGetIDictionaryCount(this IEnumerable value, out int count)
        {
            if (value is IDictionary idic)
            {
                count = idic.Count;
                return true;
            }
            else if (value is IReadOnlyDictionary irdic)
            {
                count = irdic.Count;
                return true;
            }

            count = -1;
            return false;
        }

        public static ConstructorInfo GetDefaultNoArgCtorOrAppointTypeCtor(this Type type, Type ctorParaTypes = null)
        {
            foreach (ConstructorInfo ctor in type.GetConstructors())
            {
                ParameterInfo[] ctorParas = ctor.GetParameters();
                if (ctorParas.Length == 0)
                {
                    return ctor;//no args
                }

                if (ctorParaTypes != null && ctorParas.Length == 1)
                {
                    if (ctorParas[0].ParameterType == ctorParaTypes)
                    {
                        return ctor;
                    }
                }
            }
            return null;
        }

        public static ConstructorInfo GetAppointTypeCtor(this Type type, Type ctorParaType)
        {
            foreach (ConstructorInfo ctor in type.GetConstructors())
            {
                ParameterInfo[] ctorParas = ctor.GetParameters();
                if (ctorParas.Length == 1)
                {
                    if (ctorParas[0].ParameterType == ctorParaType)
                    {
                        return ctor;
                    }
                }
            }
            return null;
        }

        public static List GetAllInterfaceMembers(this Type type)
        {
            Stack pending = new Stack();
            pending.Push(type);
            List ret = new List();
            while (pending.Count > 0)
            {
                Type current = pending.Pop();

                ret.AddRange(current.GetMembers());

                if (current.BaseType != null)
                {
                    pending.Push(current.BaseType);
                }

                foreach (Type x in current.GetInterfaces())
                {
                    pending.Push(x);
                }
            }
            return ret;
        }

        public static IEnumerable GetPublicMembersWithDynamicObject(this object value)
        {
            DEBUG.astert(value != null);
            Type t = value.GetType();
            foreach (FieldInfo p in t.GetFields(BindingFlags.Public | BindingFlags.Instance))
            {
                yield return new KeyValuePair(p.Name, p.GetValue(value));
            }
            foreach (PropertyInfo p in t.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (p.GetIndexParameters().Length == 0 && p.CanRead && p.CanWrite)
                {
                    yield return new KeyValuePair(p.Name, p.GetValue(value));
                }
            }
        }

        public static bool IsAnonymousType(this Type type)
        {
            return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
                   && type.Name.Contains("AnonymousType")
                   && (type.Name.StartsWith("") || type.Name.StartsWith("VB$"))
                   && (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
        }

        public static IEnumerable GetAllFields(this Type type, BindingFlags bind)
        {
            if (type.BaseType != null)
            {
                foreach (var item in GetAllFields(type.BaseType, bind | BindingFlags.DeclaredOnly))
                {
                    yield return item;
                }
            }

            foreach (var item in type.GetFields(bind | BindingFlags.DeclaredOnly))
            {
                yield return item;
            }
        }

        public static IEnumerable GetAllProperties(this Type type, BindingFlags bind)
        {
            if (type.BaseType != null)
            {
                foreach (var item in GetAllProperties(type.BaseType, bind | BindingFlags.DeclaredOnly))
                {
                    yield return item;
                }
            }

            foreach (var item in type.GetProperties(bind | BindingFlags.DeclaredOnly))
            {
                yield return item;
            }
        }
    }
}