Collections Data Structure C#

#region License
// Copyright 2006 James Newton-King
// http://www.newtonsoft.com
//
// This work is licensed under the Creative Commons Attribution 2.5 License
// http://creativecommons.org/licenses/by/2.5/
//
// You are free:
//    * to copy, distribute, display, and perform the work
//    * to make derivative works
//    * to make commercial use of the work
//
// Under the following conditions:
//    * You must attribute the work in the manner specified by the author or licensor:
//          - If you find this component useful a link to http://www.newtonsoft.com would be appreciated.
//    * For any reuse or distribution, you must make clear to others the license terms of this work.
//    * Any of these conditions can be waived if you get permission from the copyright holder.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace MySpace.Common.IO.JSON.Utilities
{
    internal static class CollectionUtils
    {
        /// 
        /// Determines whether the collection is null or empty.
        /// 

        /// The collection.
        /// 
        ///   true if the collection is null or empty; otherwise, false.
        /// 

        public static bool IsNullOrEmpty(ICollection collection)
        {
            if (collection != null)
            {
                return (collection.Count == 0);
            }
            return true;
        }
        /// 
        /// Determines whether the collection is null or empty.
        /// 

        /// The collection.
        /// 
        ///   true if the collection is null or empty; otherwise, false.
        /// 

        public static bool IsNullOrEmpty(ICollection collection)
        {
            if (collection != null)
            {
                return (collection.Count == 0);
            }
            return true;
        }
        /// 
        /// Determines whether the collection is null, empty or its contents are uninitialized values.
        /// 

        /// The collection.
        /// 
        ///   true if the collection is null or empty or its contents are uninitialized values; otherwise, false.
        /// 

        public static bool IsNullOrEmptyOrDefault(IList list)
        {
            if (IsNullOrEmpty(list))
                return true;
            return ItemsUnitializedValue(list);
        }
        /// 
        /// Gets the type of the typed list's items.
        /// 

        /// The type.
        /// The type of the typed list's items.
        public static Type GetTypedListItemType(Type type)
        {
            if (type == null)
                throw new ArgumentNullException("type");
            if (type.IsArray)
                return type.GetElementType();
            else if (type.IsGenericType && IsSubClass(type.GetGenericTypeDefinition(), typeof(List<>)))
                return type.GetGenericArguments()[0];
            else if (type.BaseType != null && type.BaseType.IsGenericType && IsSubClass(type.BaseType.GetGenericTypeDefinition(), typeof(List<>)))
                return type.BaseType.GetGenericArguments()[0];
            else if (type.BaseType != null && type.BaseType.BaseType != null && type.BaseType.BaseType.IsGenericType && IsSubClass(type.BaseType.BaseType.GetGenericTypeDefinition(), typeof(List<>)))
                return type.BaseType.GetGenericArguments()[0];
            else
                throw new Exception("Bad type");
        }
        public static Type GetTypedDictionaryValueType(Type type)
        {
            if (type == null)
                throw new ArgumentNullException("type");
            if (type.IsGenericType && IsSubClass(type.GetGenericTypeDefinition(), typeof(Dictionary<,>)))
                return type.GetGenericArguments()[1];
            else if (typeof(IDictionary).IsAssignableFrom(type))
                return null;
            else
                throw new Exception("Bad type");
        }
        public static bool IsSubClass(Type type, Type check)
        {
            if (type == null || check == null)
                return false;
            if (type == check && type.IsGenericType)
                return true;
            if (check.IsInterface)
            {
                foreach (Type t in type.GetInterfaces())
                {
                    if (IsSubClass(t, check)) return true;
                }
            }
            if (type.IsGenericType && !type.IsGenericTypeDefinition)
            {
                if (IsSubClass(type.GetGenericTypeDefinition(), check))
                    return true;
            }
            return IsSubClass(type.BaseType, check);
        }
        public static object GetTypeUnitializedValue(Type type)
        {
            if (type.IsValueType)
                return Activator.CreateInstance(type);
            else if (type.IsClass)
                return null;
            else
                throw new ArgumentException("Type is neither a ValueType or a Class", "type");
        }
        /// 
        /// Tests whether the list's items are their unitialized value.
        /// 

        /// The list.
        /// Whether the list's items are their unitialized value
        public static bool ItemsUnitializedValue(IList list)
        {
            if (list == null)
                throw new ArgumentNullException("values");
            Type elementType = GetTypedListItemType(list.GetType());
            if (elementType.IsValueType)
            {
                object unitializedValue = GetTypeUnitializedValue(elementType);
                for (int i = 0; i < list.Count; i++)
                {
                    if (!list[i].Equals(unitializedValue))
                        return false;
                }
            }
            else if (elementType.IsClass)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    if (list[i] != null)
                        return false;
                }
            }
            else
            {
                throw new ArgumentException("Type is neither a ValueType or a Class", "valueType");
            }
            return true;
        }
    }
}