andrew4582

Reflection Utilites

Aug 15th, 2010
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 23.51 KB | None | 0 0
  1.  
  2.  
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Text;
  6. using System.Reflection;
  7. using System.Collections;
  8. using System.ComponentModel;
  9. using System.Linq;
  10. using System.Globalization;
  11.  
  12. namespace System.Utilities
  13. {
  14.   internal delegate object MemberHandler<T>(T target, params object[] args);
  15.  
  16.   internal static class ReflectionUtils
  17.   {
  18.     public static Type GetObjectType(object v)
  19.     {
  20.       return (v != null) ? v.GetType() : null;
  21.     }
  22.  
  23.     public static bool IsInstantiatableType(Type t)
  24.     {
  25.       ValidationUtils.ArgumentNotNull(t, "t");
  26.  
  27.       if (t.IsAbstract || t.IsInterface || t.IsArray || t.IsGenericTypeDefinition || t == typeof(void))
  28.         return false;
  29.  
  30.       if (!HasDefaultConstructor(t))
  31.         return false;
  32.  
  33.       return true;
  34.     }
  35.  
  36.     public static bool HasDefaultConstructor(Type t)
  37.     {
  38.       return HasDefaultConstructor(t, false);
  39.     }
  40.  
  41.     public static bool HasDefaultConstructor(Type t, bool nonPublic)
  42.     {
  43.       ValidationUtils.ArgumentNotNull(t, "t");
  44.  
  45.       if (t.IsValueType)
  46.         return true;
  47.  
  48.       return (GetDefaultConstructor(t, nonPublic) != null);
  49.     }
  50.  
  51.     public static ConstructorInfo GetDefaultConstructor(Type t)
  52.     {
  53.       return GetDefaultConstructor(t, false);
  54.     }
  55.  
  56.     public static ConstructorInfo GetDefaultConstructor(Type t, bool nonPublic)
  57.     {
  58.       BindingFlags accessModifier = BindingFlags.Public;
  59.      
  60.       if (nonPublic)
  61.         accessModifier = accessModifier | BindingFlags.NonPublic;
  62.  
  63.       return t.GetConstructor(accessModifier | BindingFlags.Instance, null, new Type[0], null);
  64.     }
  65.  
  66.     public static bool IsNullable(Type t)
  67.     {
  68.       ValidationUtils.ArgumentNotNull(t, "t");
  69.  
  70.       if (t.IsValueType)
  71.         return IsNullableType(t);
  72.  
  73.       return true;
  74.     }
  75.  
  76.     public static bool IsNullableType(Type t)
  77.     {
  78.       ValidationUtils.ArgumentNotNull(t, "t");
  79.  
  80.       return (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
  81.     }
  82.  
  83.     //public static bool IsValueTypeUnitializedValue(ValueType value)
  84.     //{
  85.     //  if (value == null)
  86.     //    return true;
  87.  
  88.     //  return value.Equals(CreateUnitializedValue(value.GetType()));
  89.     //}
  90.  
  91.     public static bool IsUnitializedValue(object value)
  92.     {
  93.       if (value == null)
  94.       {
  95.         return true;
  96.       }
  97.       else
  98.       {
  99.         object unitializedValue = CreateUnitializedValue(value.GetType());
  100.         return value.Equals(unitializedValue);
  101.       }
  102.     }
  103.  
  104.     public static object CreateUnitializedValue(Type type)
  105.     {
  106.       ValidationUtils.ArgumentNotNull(type, "type");
  107.  
  108.       if (type.IsGenericTypeDefinition)
  109.         throw new ArgumentException("Type {0} is a generic type definition and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, type), "type");
  110.  
  111.       if (type.IsClass || type.IsInterface || type == typeof(void))
  112.         return null;
  113.       else if (type.IsValueType)
  114.         return Activator.CreateInstance(type);
  115.       else
  116.         throw new ArgumentException("Type {0} cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, type), "type");
  117.     }
  118.  
  119.     public static bool IsPropertyIndexed(PropertyInfo property)
  120.     {
  121.       ValidationUtils.ArgumentNotNull(property, "property");
  122.  
  123.       return !CollectionUtils.IsNullOrEmpty<ParameterInfo>(property.GetIndexParameters());
  124.     }
  125.  
  126.     public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition)
  127.     {
  128.       Type implementingType;
  129.       return ImplementsGenericDefinition(type, genericInterfaceDefinition, out implementingType);
  130.     }
  131.  
  132.     public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition, out Type implementingType)
  133.     {
  134.       ValidationUtils.ArgumentNotNull(type, "type");
  135.       ValidationUtils.ArgumentNotNull(genericInterfaceDefinition, "genericInterfaceDefinition");
  136.  
  137.       if (!genericInterfaceDefinition.IsInterface || !genericInterfaceDefinition.IsGenericTypeDefinition)
  138.         throw new ArgumentNullException("'{0}' is not a generic interface definition.".FormatWith(CultureInfo.InvariantCulture, genericInterfaceDefinition));
  139.  
  140.       if (type.IsInterface)
  141.       {
  142.         if (type.IsGenericType)
  143.         {
  144.           Type interfaceDefinition = type.GetGenericTypeDefinition();
  145.  
  146.           if (genericInterfaceDefinition == interfaceDefinition)
  147.           {
  148.             implementingType = type;
  149.             return true;
  150.           }
  151.         }
  152.       }
  153.  
  154.       foreach (Type i in type.GetInterfaces())
  155.       {
  156.         if (i.IsGenericType)
  157.         {
  158.           Type interfaceDefinition = i.GetGenericTypeDefinition();
  159.  
  160.           if (genericInterfaceDefinition == interfaceDefinition)
  161.           {
  162.             implementingType = i;
  163.             return true;
  164.           }
  165.         }
  166.       }
  167.  
  168.       implementingType = null;
  169.       return false;
  170.     }
  171.  
  172.     public static bool AssignableToTypeName(this Type type, string fullTypeName, out Type match)
  173.     {
  174.       Type current = type;
  175.  
  176.       while (current != null)
  177.       {
  178.         if (current.FullName == fullTypeName)
  179.         {
  180.           match = current;
  181.           return true;
  182.         }
  183.  
  184.         current = current.BaseType;
  185.       }
  186.  
  187.       foreach (Type i in type.GetInterfaces())
  188.       {
  189.         if (i.Name == fullTypeName)
  190.         {
  191.           match = type;
  192.           return true;
  193.         }
  194.       }
  195.  
  196.       match = null;
  197.       return false;
  198.     }
  199.  
  200.     public static bool AssignableToTypeName(this Type type, string fullTypeName)
  201.     {
  202.       Type match;
  203.       return type.AssignableToTypeName(fullTypeName, out match);
  204.     }
  205.  
  206.     public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition)
  207.     {
  208.       Type implementingType;
  209.       return InheritsGenericDefinition(type, genericClassDefinition, out implementingType);
  210.     }
  211.  
  212.     public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition, out Type implementingType)
  213.     {
  214.       ValidationUtils.ArgumentNotNull(type, "type");
  215.       ValidationUtils.ArgumentNotNull(genericClassDefinition, "genericClassDefinition");
  216.  
  217.       if (!genericClassDefinition.IsClass || !genericClassDefinition.IsGenericTypeDefinition)
  218.         throw new ArgumentNullException("'{0}' is not a generic class definition.".FormatWith(CultureInfo.InvariantCulture, genericClassDefinition));
  219.  
  220.       return InheritsGenericDefinitionInternal(type, type, genericClassDefinition, out implementingType);
  221.     }
  222.  
  223.     private static bool InheritsGenericDefinitionInternal(Type initialType, Type currentType, Type genericClassDefinition, out Type implementingType)
  224.     {
  225.       if (currentType.IsGenericType)
  226.       {
  227.         Type currentGenericClassDefinition = currentType.GetGenericTypeDefinition();
  228.  
  229.         if (genericClassDefinition == currentGenericClassDefinition)
  230.         {
  231.           implementingType = currentType;
  232.           return true;
  233.         }
  234.       }
  235.  
  236.       if (currentType.BaseType == null)
  237.       {
  238.         implementingType = null;
  239.         return false;
  240.       }
  241.  
  242.       return InheritsGenericDefinitionInternal(initialType, currentType.BaseType, genericClassDefinition, out implementingType);
  243.     }
  244.  
  245.     /// <summary>
  246.     /// Gets the type of the typed collection's items.
  247.     /// </summary>
  248.     /// <param name="type">The type.</param>
  249.     /// <returns>The type of the typed collection's items.</returns>
  250.     public static Type GetCollectionItemType(Type type)
  251.     {
  252.       ValidationUtils.ArgumentNotNull(type, "type");
  253.       Type genericListType;
  254.  
  255.       if (type.IsArray)
  256.       {
  257.         return type.GetElementType();
  258.       }
  259.       else if (ImplementsGenericDefinition(type, typeof(IEnumerable<>), out genericListType))
  260.       {
  261.         if (genericListType.IsGenericTypeDefinition)
  262.           throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
  263.  
  264.         return genericListType.GetGenericArguments()[0];
  265.       }
  266.       else if (typeof(IEnumerable).IsAssignableFrom(type))
  267.       {
  268.         return null;
  269.       }
  270.       else
  271.       {
  272.         throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
  273.       }
  274.     }
  275.  
  276.     public static void GetDictionaryKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType)
  277.     {
  278.       ValidationUtils.ArgumentNotNull(dictionaryType, "type");
  279.  
  280.       Type genericDictionaryType;
  281.       if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary<,>), out genericDictionaryType))
  282.       {
  283.         if (genericDictionaryType.IsGenericTypeDefinition)
  284.           throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType));
  285.  
  286.         Type[] dictionaryGenericArguments = genericDictionaryType.GetGenericArguments();
  287.  
  288.         keyType = dictionaryGenericArguments[0];
  289.         valueType = dictionaryGenericArguments[1];
  290.         return;
  291.       }
  292.       else if (typeof(IDictionary).IsAssignableFrom(dictionaryType))
  293.       {
  294.         keyType = null;
  295.         valueType = null;
  296.         return;
  297.       }
  298.       else
  299.       {
  300.         throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType));
  301.       }
  302.     }
  303.  
  304.     public static Type GetDictionaryValueType(Type dictionaryType)
  305.     {
  306.       Type keyType;
  307.       Type valueType;
  308.       GetDictionaryKeyValueTypes(dictionaryType, out keyType, out valueType);
  309.  
  310.       return valueType;
  311.     }
  312.  
  313.     public static Type GetDictionaryKeyType(Type dictionaryType)
  314.     {
  315.       Type keyType;
  316.       Type valueType;
  317.       GetDictionaryKeyValueTypes(dictionaryType, out keyType, out valueType);
  318.  
  319.       return keyType;
  320.     }
  321.  
  322.     /// <summary>
  323.     /// Tests whether the list's items are their unitialized value.
  324.     /// </summary>
  325.     /// <param name="list">The list.</param>
  326.     /// <returns>Whether the list's items are their unitialized value</returns>
  327.     public static bool ItemsUnitializedValue<T>(IList<T> list)
  328.     {
  329.       ValidationUtils.ArgumentNotNull(list, "list");
  330.  
  331.       Type elementType = GetCollectionItemType(list.GetType());
  332.  
  333.       if (elementType.IsValueType)
  334.       {
  335.         object unitializedValue = CreateUnitializedValue(elementType);
  336.  
  337.         for (int i = 0; i < list.Count; i++)
  338.         {
  339.           if (!list[i].Equals(unitializedValue))
  340.             return false;
  341.         }
  342.       }
  343.       else if (elementType.IsClass)
  344.       {
  345.         for (int i = 0; i < list.Count; i++)
  346.         {
  347.           object value = list[i];
  348.  
  349.           if (value != null)
  350.             return false;
  351.         }
  352.       }
  353.       else
  354.       {
  355.         throw new Exception("Type {0} is neither a ValueType or a Class.".FormatWith(CultureInfo.InvariantCulture, elementType));
  356.       }
  357.  
  358.       return true;
  359.     }
  360.  
  361.     /// <summary>
  362.     /// Gets the member's underlying type.
  363.     /// </summary>
  364.     /// <param name="member">The member.</param>
  365.     /// <returns>The underlying type of the member.</returns>
  366.     public static Type GetMemberUnderlyingType(MemberInfo member)
  367.     {
  368.       ValidationUtils.ArgumentNotNull(member, "member");
  369.  
  370.       switch (member.MemberType)
  371.       {
  372.         case MemberTypes.Field:
  373.           return ((FieldInfo)member).FieldType;
  374.         case MemberTypes.Property:
  375.           return ((PropertyInfo)member).PropertyType;
  376.         case MemberTypes.Event:
  377.           return ((EventInfo)member).EventHandlerType;
  378.         default:
  379.           throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or EventInfo", "member");
  380.       }
  381.     }
  382.  
  383.     /// <summary>
  384.     /// Determines whether the member is an indexed property.
  385.     /// </summary>
  386.     /// <param name="member">The member.</param>
  387.     /// <returns>
  388.     ///     <c>true</c> if the member is an indexed property; otherwise, <c>false</c>.
  389.     /// </returns>
  390.     public static bool IsIndexedProperty(MemberInfo member)
  391.     {
  392.       ValidationUtils.ArgumentNotNull(member, "member");
  393.  
  394.       PropertyInfo propertyInfo = member as PropertyInfo;
  395.  
  396.       if (propertyInfo != null)
  397.         return IsIndexedProperty(propertyInfo);
  398.       else
  399.         return false;
  400.     }
  401.  
  402.     /// <summary>
  403.     /// Determines whether the property is an indexed property.
  404.     /// </summary>
  405.     /// <param name="property">The property.</param>
  406.     /// <returns>
  407.     ///     <c>true</c> if the property is an indexed property; otherwise, <c>false</c>.
  408.     /// </returns>
  409.     public static bool IsIndexedProperty(PropertyInfo property)
  410.     {
  411.       ValidationUtils.ArgumentNotNull(property, "property");
  412.  
  413.       return (property.GetIndexParameters().Length > 0);
  414.     }
  415.  
  416.     /// <summary>
  417.     /// Gets the member's value on the object.
  418.     /// </summary>
  419.     /// <param name="member">The member.</param>
  420.     /// <param name="target">The target object.</param>
  421.     /// <returns>The member's value on the object.</returns>
  422.     public static object GetMemberValue(MemberInfo member, object target)
  423.     {
  424.       ValidationUtils.ArgumentNotNull(member, "member");
  425.       ValidationUtils.ArgumentNotNull(target, "target");
  426.  
  427.       switch (member.MemberType)
  428.       {
  429.         case MemberTypes.Field:
  430.           return ((FieldInfo)member).GetValue(target);
  431.         case MemberTypes.Property:
  432.           try
  433.           {
  434.             return ((PropertyInfo)member).GetValue(target, null);
  435.           }
  436.           catch (TargetParameterCountException e)
  437.           {
  438.             throw new ArgumentException("MemberInfo '{0}' has index parameters".FormatWith(CultureInfo.InvariantCulture, member.Name), e);
  439.           }
  440.         default:
  441.           throw new ArgumentException("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture, member.Name), "member");
  442.       }
  443.     }
  444.  
  445.     /// <summary>
  446.     /// Sets the member's value on the target object.
  447.     /// </summary>
  448.     /// <param name="member">The member.</param>
  449.     /// <param name="target">The target.</param>
  450.     /// <param name="value">The value.</param>
  451.     public static void SetMemberValue(MemberInfo member, object target, object value)
  452.     {
  453.       ValidationUtils.ArgumentNotNull(member, "member");
  454.       ValidationUtils.ArgumentNotNull(target, "target");
  455.  
  456.       switch (member.MemberType)
  457.       {
  458.         case MemberTypes.Field:
  459.           ((FieldInfo)member).SetValue(target, value);
  460.           break;
  461.         case MemberTypes.Property:
  462.           ((PropertyInfo)member).SetValue(target, value, null);
  463.           break;
  464.         default:
  465.           throw new ArgumentException("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), "member");
  466.       }
  467.     }
  468.  
  469.     /// <summary>
  470.     /// Determines whether the specified MemberInfo can be read.
  471.     /// </summary>
  472.     /// <param name="member">The MemberInfo to determine whether can be read.</param>
  473.     /// <returns>
  474.     ///     <c>true</c> if the specified MemberInfo can be read; otherwise, <c>false</c>.
  475.     /// </returns>
  476.     public static bool CanReadMemberValue(MemberInfo member)
  477.     {
  478.       switch (member.MemberType)
  479.       {
  480.         case MemberTypes.Field:
  481.           return true;
  482.         case MemberTypes.Property:
  483.           return ((PropertyInfo)member).CanRead;
  484.         default:
  485.           return false;
  486.       }
  487.     }
  488.  
  489.     /// <summary>
  490.     /// Determines whether the specified MemberInfo can be set.
  491.     /// </summary>
  492.     /// <param name="member">The MemberInfo to determine whether can be set.</param>
  493.     /// <returns>
  494.     ///     <c>true</c> if the specified MemberInfo can be set; otherwise, <c>false</c>.
  495.     /// </returns>
  496.     public static bool CanSetMemberValue(MemberInfo member)
  497.     {
  498.       switch (member.MemberType)
  499.       {
  500.         case MemberTypes.Field:
  501.           return !((FieldInfo)member).IsInitOnly;
  502.         case MemberTypes.Property:
  503.           return ((PropertyInfo)member).CanWrite;
  504.         default:
  505.           return false;
  506.       }
  507.     }
  508.  
  509.     public static List<MemberInfo> GetFieldsAndProperties<T>(BindingFlags bindingAttr)
  510.     {
  511.       return GetFieldsAndProperties(typeof(T), bindingAttr);
  512.     }
  513.  
  514.     public static List<MemberInfo> GetFieldsAndProperties(Type type, BindingFlags bindingAttr)
  515.     {
  516.       List<MemberInfo> targetMembers = new List<MemberInfo>();
  517.  
  518.       targetMembers.AddRange(type.GetFields(bindingAttr));
  519.       targetMembers.AddRange(type.GetProperties(bindingAttr));
  520.  
  521.       // for some reason .NET returns multiple members when overriding a generic member on a base class
  522.       // http://forums.msdn.microsoft.com/en-US/netfxbcl/thread/b5abbfee-e292-4a64-8907-4e3f0fb90cd9/
  523.       // filter members to only return the override on the topmost class
  524.       List<MemberInfo> distinctMembers = new List<MemberInfo>(targetMembers.Count);
  525.  
  526.       var groupedMembers = targetMembers.GroupBy(m => m.Name).Select(g => new { Count = g.Count(), Members = g.Cast<MemberInfo>() });
  527.       foreach (var groupedMember in groupedMembers)
  528.       {
  529.         if (groupedMember.Count == 1)
  530.           distinctMembers.Add(groupedMember.Members.First());
  531.         else
  532.           distinctMembers.Add(groupedMember.Members.Where(m => !IsOverridenGenericMember(m, bindingAttr)).First());
  533.       }
  534.  
  535.       return distinctMembers;
  536.     }
  537.  
  538.     private static bool IsOverridenGenericMember(MemberInfo memberInfo, BindingFlags bindingAttr)
  539.     {
  540.       if (memberInfo.MemberType != MemberTypes.Field && memberInfo.MemberType != MemberTypes.Property)
  541.         throw new ArgumentException("Member must be a field or property.");
  542.  
  543.       Type declaringType = memberInfo.DeclaringType;
  544.       if (!declaringType.IsGenericType)
  545.         return false;
  546.       Type genericTypeDefinition = declaringType.GetGenericTypeDefinition();
  547.       if (genericTypeDefinition == null)
  548.         return false;
  549.       MemberInfo[] members = genericTypeDefinition.GetMember(memberInfo.Name, bindingAttr);
  550.       if (members.Length == 0)
  551.         return false;
  552.       Type memberUnderlyingType = GetMemberUnderlyingType(members[0]);
  553.       if (!memberUnderlyingType.IsGenericParameter)
  554.         return false;
  555.  
  556.       return true;
  557.     }
  558.  
  559.     public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
  560.     {
  561.       return GetAttribute<T>(attributeProvider, true);
  562.     }
  563.  
  564.     public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
  565.     {
  566.       T[] attributes = GetAttributes<T>(attributeProvider, inherit);
  567.  
  568.       return CollectionUtils.GetSingleItem(attributes, true);
  569.     }
  570.  
  571.     public static T[] GetAttributes<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
  572.     {
  573.       ValidationUtils.ArgumentNotNull(attributeProvider, "attributeProvider");
  574.  
  575.       return (T[])attributeProvider.GetCustomAttributes(typeof(T), inherit);
  576.     }
  577.  
  578.     public static string GetNameAndAssessmblyName(Type t)
  579.     {
  580.       ValidationUtils.ArgumentNotNull(t, "t");
  581.  
  582.       return t.FullName + ", " + t.Assembly.GetName().Name;
  583.     }
  584.  
  585.     public static Type MakeGenericType(Type genericTypeDefinition, params Type[] innerTypes)
  586.     {
  587.       ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
  588.       ValidationUtils.ArgumentNotNullOrEmpty<Type>(innerTypes, "innerTypes");
  589.       ValidationUtils.ArgumentConditionTrue(genericTypeDefinition.IsGenericTypeDefinition, "genericTypeDefinition", "Type {0} is not a generic type definition.".FormatWith(CultureInfo.InvariantCulture, genericTypeDefinition));
  590.  
  591.       return genericTypeDefinition.MakeGenericType(innerTypes);
  592.     }
  593.  
  594.     public static object CreateGeneric(Type genericTypeDefinition, Type innerType, params object[] args)
  595.     {
  596.       return CreateGeneric(genericTypeDefinition, new Type[] { innerType }, args);
  597.     }
  598.  
  599.     public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, params object[] args)
  600.     {
  601.       return CreateGeneric(genericTypeDefinition, innerTypes, (t, a) => ReflectionUtils.CreateInstance(t, a.ToArray()), args);
  602.     }
  603.  
  604.     public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, Func<Type, IList<object>, object> instanceCreator, params object[] args)
  605.     {
  606.       ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
  607.       ValidationUtils.ArgumentNotNullOrEmpty(innerTypes, "innerTypes");
  608.       ValidationUtils.ArgumentNotNull(instanceCreator, "createInstance");
  609.  
  610.       Type specificType = MakeGenericType(genericTypeDefinition, innerTypes.ToArray());
  611.  
  612.       return instanceCreator(specificType, args);
  613.     }
  614.  
  615.      public static bool IsCompatibleValue(object value, Type type)
  616.      {
  617.        if (value == null && IsNullable(type))
  618.          return true;
  619.  
  620.        if (type.IsAssignableFrom(value.GetType()))
  621.          return true;
  622.  
  623.        return false;
  624.      }
  625.  
  626.      public static object CreateInstance(Type type, params object[] args)
  627.      {
  628.        ValidationUtils.ArgumentNotNull(type, "type");
  629.  
  630. #if !PocketPC
  631.        return Activator.CreateInstance(type, args);
  632. #else
  633.        if (type.IsValueType)
  634.          return Activator.CreateInstance(type);
  635.  
  636.        ConstructorInfo[] constructors = type.GetConstructors();
  637.        ConstructorInfo match = constructors.Where(c =>
  638.          {
  639.            ParameterInfo[] parameters = c.GetParameters();
  640.            if (parameters.Length != args.Length)
  641.              return false;
  642.  
  643.            for (int i = 0; i < parameters.Length; i++)
  644.            {
  645.              ParameterInfo parameter = parameters[i];
  646.              object value = args[i];
  647.  
  648.              if (!IsCompatibleValue(value, parameter.ParameterType))
  649.                return false;
  650.            }
  651.  
  652.            return true;
  653.          }).FirstOrDefault();
  654.  
  655.        if (match == null)
  656.          throw new Exception("Could not create '{0}' with given parameters.".FormatWith(CultureInfo.InvariantCulture, type));
  657.  
  658.        return match.Invoke(args);
  659. #endif
  660.      }
  661.  
  662.     public static void SplitFullyQualifiedTypeName(string fullyQualifiedTypeName, out string typeName, out string assemblyName)
  663.     {
  664.       int? assemblyDelimiterIndex = GetAssemblyDelimiterIndex(fullyQualifiedTypeName);
  665.  
  666.       if (assemblyDelimiterIndex != null)
  667.       {
  668.         typeName = fullyQualifiedTypeName.Substring(0, assemblyDelimiterIndex.Value).Trim();
  669.         assemblyName = fullyQualifiedTypeName.Substring(assemblyDelimiterIndex.Value + 1, fullyQualifiedTypeName.Length - assemblyDelimiterIndex.Value - 1).Trim();
  670.       }
  671.       else
  672.       {
  673.         typeName = fullyQualifiedTypeName;
  674.         assemblyName = null;
  675.       }
  676.  
  677.     }
  678.  
  679.     private static int? GetAssemblyDelimiterIndex(string fullyQualifiedTypeName)
  680.     {
  681.       // we need to get the first comma following all surrounded in brackets because of generic types
  682.       // e.g. System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
  683.       int scope = 0;
  684.       for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
  685.       {
  686.         char current = fullyQualifiedTypeName[i];
  687.         switch (current)
  688.         {
  689.           case '[':
  690.             scope++;
  691.             break;
  692.           case ']':
  693.             scope--;
  694.             break;
  695.           case ',':
  696.             if (scope == 0)
  697.               return i;
  698.             break;
  699.         }
  700.       }
  701.  
  702.       return null;
  703.     }
  704.   }
  705. }
Advertisement
Add Comment
Please, Sign In to add comment