2
// Copyright (c) 2007 James Newton-King
4
// Permission is hereby granted, free of charge, to any person
5
// obtaining a copy of this software and associated documentation
6
// files (the "Software"), to deal in the Software without
7
// restriction, including without limitation the rights to use,
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
// OTHER DEALINGS IN THE SOFTWARE.
27
using System.Collections.Generic;
28
using System.Reflection;
29
using System.Collections;
30
using System.Globalization;
31
using System.Runtime.Serialization;
32
using System.Runtime.Serialization.Formatters;
35
using IConvertible = Newtonsoft.Json.Utilities.Convertible;
37
#if NETFX_CORE || PORTABLE
38
using ICustomAttributeProvider = Newtonsoft.Json.Utilities.CustomAttributeProvider;
41
using Newtonsoft.Json.Utilities.LinqBridge;
45
using Newtonsoft.Json.Serialization;
47
namespace Newtonsoft.Json.Utilities
49
#if NETFX_CORE || PORTABLE
50
internal enum MemberTypes
59
internal class CustomAttributeProvider
61
private readonly object _underlyingObject;
63
public CustomAttributeProvider(object o)
65
_underlyingObject = o;
68
public object UnderlyingObject
70
get { return _underlyingObject; }
76
internal enum TypeCode
98
internal enum BindingFlags
107
FlattenHierarchy = 64,
109
CreateInstance = 512,
114
PutDispProperty = 16384,
115
ExactBinding = 65536,
116
PutRefDispProperty = 32768,
117
SuppressChangeType = 131072,
118
OptionalParamBinding = 262144,
119
IgnoreReturn = 16777216
123
internal static class ReflectionUtils
125
public static readonly Type[] EmptyTypes;
127
static ReflectionUtils()
129
#if !(NETFX_CORE || PORTABLE)
130
EmptyTypes = Type.EmptyTypes;
132
EmptyTypes = new Type[0];
136
public static ICustomAttributeProvider GetCustomAttributeProvider(this object o)
138
#if !(NETFX_CORE || PORTABLE)
139
return (ICustomAttributeProvider)o;
141
return new ICustomAttributeProvider(o);
145
public static bool IsVirtual(this PropertyInfo propertyInfo)
147
ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo");
149
MethodInfo m = propertyInfo.GetGetMethod();
150
if (m != null && m.IsVirtual)
153
m = propertyInfo.GetSetMethod();
154
if (m != null && m.IsVirtual)
160
public static Type GetObjectType(object v)
162
return (v != null) ? v.GetType() : null;
165
public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat)
167
return GetTypeName(t, assemblyFormat, null);
170
public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat, SerializationBinder binder)
172
string fullyQualifiedTypeName;
173
#if !(NET20 || NET35)
176
string assemblyName, typeName;
177
binder.BindToName(t, out assemblyName, out typeName);
178
fullyQualifiedTypeName = typeName + (assemblyName == null ? "" : ", " + assemblyName);
182
fullyQualifiedTypeName = t.AssemblyQualifiedName;
185
fullyQualifiedTypeName = t.AssemblyQualifiedName;
188
switch (assemblyFormat)
190
case FormatterAssemblyStyle.Simple:
191
return RemoveAssemblyDetails(fullyQualifiedTypeName);
192
case FormatterAssemblyStyle.Full:
193
return fullyQualifiedTypeName;
195
throw new ArgumentOutOfRangeException();
199
private static string RemoveAssemblyDetails(string fullyQualifiedTypeName)
201
StringBuilder builder = new StringBuilder();
203
// loop through the type name and filter out qualified assembly details from nested type names
204
bool writingAssemblyName = false;
205
bool skippingAssemblyDetails = false;
206
for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
208
char current = fullyQualifiedTypeName[i];
212
writingAssemblyName = false;
213
skippingAssemblyDetails = false;
214
builder.Append(current);
217
writingAssemblyName = false;
218
skippingAssemblyDetails = false;
219
builder.Append(current);
222
if (!writingAssemblyName)
224
writingAssemblyName = true;
225
builder.Append(current);
229
skippingAssemblyDetails = true;
233
if (!skippingAssemblyDetails)
234
builder.Append(current);
239
return builder.ToString();
242
public static bool IsInstantiatableType(Type t)
244
ValidationUtils.ArgumentNotNull(t, "t");
246
if (t.IsAbstract() || t.IsInterface() || t.IsArray || t.IsGenericTypeDefinition() || t == typeof(void))
249
if (!HasDefaultConstructor(t))
255
public static bool HasDefaultConstructor(Type t)
257
return HasDefaultConstructor(t, false);
260
public static bool HasDefaultConstructor(Type t, bool nonPublic)
262
ValidationUtils.ArgumentNotNull(t, "t");
267
return (GetDefaultConstructor(t, nonPublic) != null);
270
public static ConstructorInfo GetDefaultConstructor(Type t)
272
return GetDefaultConstructor(t, false);
275
public static ConstructorInfo GetDefaultConstructor(Type t, bool nonPublic)
277
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;
279
bindingFlags = bindingFlags | BindingFlags.NonPublic;
281
return t.GetConstructors(bindingFlags).SingleOrDefault(c => !c.GetParameters().Any());
284
public static bool IsNullable(Type t)
286
ValidationUtils.ArgumentNotNull(t, "t");
289
return IsNullableType(t);
294
public static bool IsNullableType(Type t)
296
ValidationUtils.ArgumentNotNull(t, "t");
298
return (t.IsGenericType() && t.GetGenericTypeDefinition() == typeof(Nullable<>));
301
public static Type EnsureNotNullableType(Type t)
303
return (IsNullableType(t))
304
? Nullable.GetUnderlyingType(t)
308
public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition)
310
Type implementingType;
311
return ImplementsGenericDefinition(type, genericInterfaceDefinition, out implementingType);
314
public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition, out Type implementingType)
316
ValidationUtils.ArgumentNotNull(type, "type");
317
ValidationUtils.ArgumentNotNull(genericInterfaceDefinition, "genericInterfaceDefinition");
319
if (!genericInterfaceDefinition.IsInterface() || !genericInterfaceDefinition.IsGenericTypeDefinition())
320
throw new ArgumentNullException("'{0}' is not a generic interface definition.".FormatWith(CultureInfo.InvariantCulture, genericInterfaceDefinition));
322
if (type.IsInterface())
324
if (type.IsGenericType())
326
Type interfaceDefinition = type.GetGenericTypeDefinition();
328
if (genericInterfaceDefinition == interfaceDefinition)
330
implementingType = type;
336
foreach (Type i in type.GetInterfaces())
338
if (i.IsGenericType())
340
Type interfaceDefinition = i.GetGenericTypeDefinition();
342
if (genericInterfaceDefinition == interfaceDefinition)
344
implementingType = i;
350
implementingType = null;
354
public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition)
356
Type implementingType;
357
return InheritsGenericDefinition(type, genericClassDefinition, out implementingType);
360
public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition, out Type implementingType)
362
ValidationUtils.ArgumentNotNull(type, "type");
363
ValidationUtils.ArgumentNotNull(genericClassDefinition, "genericClassDefinition");
365
if (!genericClassDefinition.IsClass() || !genericClassDefinition.IsGenericTypeDefinition())
366
throw new ArgumentNullException("'{0}' is not a generic class definition.".FormatWith(CultureInfo.InvariantCulture, genericClassDefinition));
368
return InheritsGenericDefinitionInternal(type, genericClassDefinition, out implementingType);
371
private static bool InheritsGenericDefinitionInternal(Type currentType, Type genericClassDefinition, out Type implementingType)
373
if (currentType.IsGenericType())
375
Type currentGenericClassDefinition = currentType.GetGenericTypeDefinition();
377
if (genericClassDefinition == currentGenericClassDefinition)
379
implementingType = currentType;
384
if (currentType.BaseType() == null)
386
implementingType = null;
390
return InheritsGenericDefinitionInternal(currentType.BaseType(), genericClassDefinition, out implementingType);
394
/// Gets the type of the typed collection's items.
396
/// <param name="type">The type.</param>
397
/// <returns>The type of the typed collection's items.</returns>
398
public static Type GetCollectionItemType(Type type)
400
ValidationUtils.ArgumentNotNull(type, "type");
401
Type genericListType;
405
return type.GetElementType();
407
else if (ImplementsGenericDefinition(type, typeof(IEnumerable<>), out genericListType))
409
if (genericListType.IsGenericTypeDefinition())
410
throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
412
return genericListType.GetGenericArguments()[0];
414
else if (typeof(IEnumerable).IsAssignableFrom(type))
420
throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
424
public static void GetDictionaryKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType)
426
ValidationUtils.ArgumentNotNull(dictionaryType, "type");
428
Type genericDictionaryType;
429
if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary<,>), out genericDictionaryType))
431
if (genericDictionaryType.IsGenericTypeDefinition())
432
throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType));
434
Type[] dictionaryGenericArguments = genericDictionaryType.GetGenericArguments();
436
keyType = dictionaryGenericArguments[0];
437
valueType = dictionaryGenericArguments[1];
440
else if (typeof(IDictionary).IsAssignableFrom(dictionaryType))
448
throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType));
452
public static Type GetDictionaryValueType(Type dictionaryType)
456
GetDictionaryKeyValueTypes(dictionaryType, out keyType, out valueType);
461
public static Type GetDictionaryKeyType(Type dictionaryType)
465
GetDictionaryKeyValueTypes(dictionaryType, out keyType, out valueType);
471
/// Gets the member's underlying type.
473
/// <param name="member">The member.</param>
474
/// <returns>The underlying type of the member.</returns>
475
public static Type GetMemberUnderlyingType(MemberInfo member)
477
ValidationUtils.ArgumentNotNull(member, "member");
479
switch (member.MemberType())
481
case MemberTypes.Field:
482
return ((FieldInfo)member).FieldType;
483
case MemberTypes.Property:
484
return ((PropertyInfo)member).PropertyType;
485
case MemberTypes.Event:
486
return ((EventInfo)member).EventHandlerType;
488
throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or EventInfo", "member");
493
/// Determines whether the member is an indexed property.
495
/// <param name="member">The member.</param>
497
/// <c>true</c> if the member is an indexed property; otherwise, <c>false</c>.
499
public static bool IsIndexedProperty(MemberInfo member)
501
ValidationUtils.ArgumentNotNull(member, "member");
503
PropertyInfo propertyInfo = member as PropertyInfo;
505
if (propertyInfo != null)
506
return IsIndexedProperty(propertyInfo);
512
/// Determines whether the property is an indexed property.
514
/// <param name="property">The property.</param>
516
/// <c>true</c> if the property is an indexed property; otherwise, <c>false</c>.
518
public static bool IsIndexedProperty(PropertyInfo property)
520
ValidationUtils.ArgumentNotNull(property, "property");
522
return (property.GetIndexParameters().Length > 0);
526
/// Gets the member's value on the object.
528
/// <param name="member">The member.</param>
529
/// <param name="target">The target object.</param>
530
/// <returns>The member's value on the object.</returns>
531
public static object GetMemberValue(MemberInfo member, object target)
533
ValidationUtils.ArgumentNotNull(member, "member");
534
ValidationUtils.ArgumentNotNull(target, "target");
536
switch (member.MemberType())
538
case MemberTypes.Field:
539
return ((FieldInfo)member).GetValue(target);
540
case MemberTypes.Property:
543
return ((PropertyInfo)member).GetValue(target, null);
545
catch (TargetParameterCountException e)
547
throw new ArgumentException("MemberInfo '{0}' has index parameters".FormatWith(CultureInfo.InvariantCulture, member.Name), e);
550
throw new ArgumentException("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture, member.Name), "member");
555
/// Sets the member's value on the target object.
557
/// <param name="member">The member.</param>
558
/// <param name="target">The target.</param>
559
/// <param name="value">The value.</param>
560
public static void SetMemberValue(MemberInfo member, object target, object value)
562
ValidationUtils.ArgumentNotNull(member, "member");
563
ValidationUtils.ArgumentNotNull(target, "target");
565
switch (member.MemberType())
567
case MemberTypes.Field:
568
((FieldInfo)member).SetValue(target, value);
570
case MemberTypes.Property:
571
((PropertyInfo)member).SetValue(target, value, null);
574
throw new ArgumentException("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), "member");
579
/// Determines whether the specified MemberInfo can be read.
581
/// <param name="member">The MemberInfo to determine whether can be read.</param>
582
/// /// <param name="nonPublic">if set to <c>true</c> then allow the member to be gotten non-publicly.</param>
584
/// <c>true</c> if the specified MemberInfo can be read; otherwise, <c>false</c>.
586
public static bool CanReadMemberValue(MemberInfo member, bool nonPublic)
588
switch (member.MemberType())
590
case MemberTypes.Field:
591
FieldInfo fieldInfo = (FieldInfo)member;
595
else if (fieldInfo.IsPublic)
598
case MemberTypes.Property:
599
PropertyInfo propertyInfo = (PropertyInfo) member;
601
if (!propertyInfo.CanRead)
605
return (propertyInfo.GetGetMethod(nonPublic) != null);
612
/// Determines whether the specified MemberInfo can be set.
614
/// <param name="member">The MemberInfo to determine whether can be set.</param>
615
/// <param name="nonPublic">if set to <c>true</c> then allow the member to be set non-publicly.</param>
616
/// <param name="canSetReadOnly">if set to <c>true</c> then allow the member to be set if read-only.</param>
618
/// <c>true</c> if the specified MemberInfo can be set; otherwise, <c>false</c>.
620
public static bool CanSetMemberValue(MemberInfo member, bool nonPublic, bool canSetReadOnly)
622
switch (member.MemberType())
624
case MemberTypes.Field:
625
FieldInfo fieldInfo = (FieldInfo)member;
627
if (fieldInfo.IsInitOnly && !canSetReadOnly)
631
else if (fieldInfo.IsPublic)
634
case MemberTypes.Property:
635
PropertyInfo propertyInfo = (PropertyInfo)member;
637
if (!propertyInfo.CanWrite)
641
return (propertyInfo.GetSetMethod(nonPublic) != null);
647
public static List<MemberInfo> GetFieldsAndProperties(Type type, BindingFlags bindingAttr)
649
List<MemberInfo> targetMembers = new List<MemberInfo>();
651
targetMembers.AddRange(GetFields(type, bindingAttr));
652
targetMembers.AddRange(GetProperties(type, bindingAttr));
654
// for some reason .NET returns multiple members when overriding a generic member on a base class
655
// http://forums.msdn.microsoft.com/en-US/netfxbcl/thread/b5abbfee-e292-4a64-8907-4e3f0fb90cd9/
656
// filter members to only return the override on the topmost class
657
// update: I think this is fixed in .NET 3.5 SP1 - leave this in for now...
658
List<MemberInfo> distinctMembers = new List<MemberInfo>(targetMembers.Count);
660
foreach (var groupedMember in targetMembers.GroupBy(m => m.Name))
662
int count = groupedMember.Count();
663
IList<MemberInfo> members = groupedMember.ToList();
667
distinctMembers.Add(members.First());
671
var resolvedMembers = members.Where(m => !IsOverridenGenericMember(m, bindingAttr) || m.Name == "Item");
673
distinctMembers.AddRange(resolvedMembers);
677
return distinctMembers;
681
private static bool IsOverridenGenericMember(MemberInfo memberInfo, BindingFlags bindingAttr)
683
MemberTypes memberType = memberInfo.MemberType();
684
if (memberType != MemberTypes.Field && memberType != MemberTypes.Property)
685
throw new ArgumentException("Member must be a field or property.");
687
Type declaringType = memberInfo.DeclaringType;
688
if (!declaringType.IsGenericType())
690
Type genericTypeDefinition = declaringType.GetGenericTypeDefinition();
691
if (genericTypeDefinition == null)
693
MemberInfo[] members = genericTypeDefinition.GetMember(memberInfo.Name, bindingAttr);
694
if (members.Length == 0)
696
Type memberUnderlyingType = GetMemberUnderlyingType(members[0]);
697
if (!memberUnderlyingType.IsGenericParameter)
703
public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
705
return GetAttribute<T>(attributeProvider, true);
708
public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
710
T[] attributes = GetAttributes<T>(attributeProvider, inherit);
712
return (attributes != null) ? attributes.SingleOrDefault() : null;
716
public static T[] GetAttributes<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
718
ValidationUtils.ArgumentNotNull(attributeProvider, "attributeProvider");
723
provider = attributeProvider;
725
provider = attributeProvider.UnderlyingObject;
728
// http://hyperthink.net/blog/getcustomattributes-gotcha/
729
// ICustomAttributeProvider doesn't do inheritance
731
if (provider is Type)
732
return (T[])((Type)provider).GetCustomAttributes(typeof(T), inherit);
734
if (provider is Assembly)
735
return (T[])Attribute.GetCustomAttributes((Assembly)provider, typeof(T));
737
if (provider is MemberInfo)
738
return (T[])Attribute.GetCustomAttributes((MemberInfo)provider, typeof(T), inherit);
741
if (provider is Module)
742
return (T[])Attribute.GetCustomAttributes((Module)provider, typeof(T), inherit);
745
if (provider is ParameterInfo)
746
return (T[])Attribute.GetCustomAttributes((ParameterInfo)provider, typeof(T), inherit);
749
return (T[])attributeProvider.GetCustomAttributes(typeof(T), inherit);
751
throw new Exception("Cannot get attributes from '{0}'.".FormatWith(CultureInfo.InvariantCulture, provider));
755
public static T[] GetAttributes<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
757
object provider = attributeProvider.UnderlyingObject;
759
if (provider is Type)
760
return ((Type)provider).GetTypeInfo().GetCustomAttributes<T>(inherit).ToArray();
762
if (provider is Assembly)
763
return ((Assembly)provider).GetCustomAttributes<T>().ToArray();
765
if (provider is MemberInfo)
766
return ((MemberInfo)provider).GetCustomAttributes<T>(inherit).ToArray();
768
if (provider is Module)
769
return ((Module)provider).GetCustomAttributes<T>().ToArray();
771
if (provider is ParameterInfo)
772
return ((ParameterInfo)provider).GetCustomAttributes<T>(inherit).ToArray();
774
throw new Exception("Cannot get attributes from '{0}'.".FormatWith(CultureInfo.InvariantCulture, provider));
778
public static Type MakeGenericType(Type genericTypeDefinition, params Type[] innerTypes)
780
ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
781
ValidationUtils.ArgumentNotNullOrEmpty<Type>(innerTypes, "innerTypes");
782
ValidationUtils.ArgumentConditionTrue(genericTypeDefinition.IsGenericTypeDefinition(), "genericTypeDefinition", "Type {0} is not a generic type definition.".FormatWith(CultureInfo.InvariantCulture, genericTypeDefinition));
784
return genericTypeDefinition.MakeGenericType(innerTypes);
787
public static object CreateGeneric(Type genericTypeDefinition, Type innerType, params object[] args)
789
return CreateGeneric(genericTypeDefinition, new [] { innerType }, args);
792
public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, params object[] args)
794
return CreateGeneric(genericTypeDefinition, innerTypes, (t, a) => CreateInstance(t, a.ToArray()), args);
797
public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, Func<Type, IList<object>, object> instanceCreator, params object[] args)
799
ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
800
ValidationUtils.ArgumentNotNullOrEmpty(innerTypes, "innerTypes");
801
ValidationUtils.ArgumentNotNull(instanceCreator, "createInstance");
803
Type specificType = MakeGenericType(genericTypeDefinition, innerTypes.ToArray());
805
return instanceCreator(specificType, args);
808
public static object CreateInstance(Type type, params object[] args)
810
ValidationUtils.ArgumentNotNull(type, "type");
813
return Activator.CreateInstance(type, args);
815
// CF doesn't have a Activator.CreateInstance overload that takes args
818
if (type.IsValueType && CollectionUtils.IsNullOrEmpty<object>(args))
819
return Activator.CreateInstance(type);
821
ConstructorInfo[] constructors = type.GetConstructors();
822
ConstructorInfo match = constructors.Where(c =>
824
ParameterInfo[] parameters = c.GetParameters();
825
if (parameters.Length != args.Length)
828
for (int i = 0; i < parameters.Length; i++)
830
ParameterInfo parameter = parameters[i];
831
object value = args[i];
833
if (!IsCompatibleValue(value, parameter.ParameterType))
841
throw new Exception("Could not create '{0}' with given parameters.".FormatWith(CultureInfo.InvariantCulture, type));
843
return match.Invoke(args);
847
public static void SplitFullyQualifiedTypeName(string fullyQualifiedTypeName, out string typeName, out string assemblyName)
849
int? assemblyDelimiterIndex = GetAssemblyDelimiterIndex(fullyQualifiedTypeName);
851
if (assemblyDelimiterIndex != null)
853
typeName = fullyQualifiedTypeName.Substring(0, assemblyDelimiterIndex.Value).Trim();
854
assemblyName = fullyQualifiedTypeName.Substring(assemblyDelimiterIndex.Value + 1, fullyQualifiedTypeName.Length - assemblyDelimiterIndex.Value - 1).Trim();
858
typeName = fullyQualifiedTypeName;
864
private static int? GetAssemblyDelimiterIndex(string fullyQualifiedTypeName)
866
// we need to get the first comma following all surrounded in brackets because of generic types
867
// 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
869
for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
871
char current = fullyQualifiedTypeName[i];
890
public static MemberInfo GetMemberInfoFromType(Type targetType, MemberInfo memberInfo)
892
const BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
894
switch (memberInfo.MemberType())
896
case MemberTypes.Property:
897
PropertyInfo propertyInfo = (PropertyInfo) memberInfo;
899
Type[] types = propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray();
901
return targetType.GetProperty(propertyInfo.Name, bindingAttr, null, propertyInfo.PropertyType, types, null);
903
return targetType.GetMember(memberInfo.Name, memberInfo.MemberType(), bindingAttr).SingleOrDefault();
907
public static IEnumerable<FieldInfo> GetFields(Type targetType, BindingFlags bindingAttr)
909
ValidationUtils.ArgumentNotNull(targetType, "targetType");
911
List<MemberInfo> fieldInfos = new List<MemberInfo>(targetType.GetFields(bindingAttr));
913
// Type.GetFields doesn't return inherited private fields
914
// manually find private fields from base class
915
GetChildPrivateFields(fieldInfos, targetType, bindingAttr);
918
return fieldInfos.Cast<FieldInfo>();
921
private static void GetChildPrivateFields(IList<MemberInfo> initialFields, Type targetType, BindingFlags bindingAttr)
923
// fix weirdness with private FieldInfos only being returned for the current Type
924
// find base type fields and add them to result
925
if ((bindingAttr & BindingFlags.NonPublic) != 0)
927
// modify flags to not search for public fields
928
BindingFlags nonPublicBindingAttr = bindingAttr.RemoveFlag(BindingFlags.Public);
930
while ((targetType = targetType.BaseType()) != null)
932
// filter out protected fields
933
IEnumerable<MemberInfo> childPrivateFields =
934
targetType.GetFields(nonPublicBindingAttr).Where(f => f.IsPrivate).Cast<MemberInfo>();
936
initialFields.AddRange(childPrivateFields);
941
public static IEnumerable<PropertyInfo> GetProperties(Type targetType, BindingFlags bindingAttr)
943
ValidationUtils.ArgumentNotNull(targetType, "targetType");
945
List<PropertyInfo> propertyInfos = new List<PropertyInfo>(targetType.GetProperties(bindingAttr));
946
GetChildPrivateProperties(propertyInfos, targetType, bindingAttr);
948
// a base class private getter/setter will be inaccessable unless the property was gotten from the base class
949
for (int i = 0; i < propertyInfos.Count; i++)
951
PropertyInfo member = propertyInfos[i];
952
if (member.DeclaringType != targetType)
954
PropertyInfo declaredMember = (PropertyInfo)GetMemberInfoFromType(member.DeclaringType, member);
955
propertyInfos[i] = declaredMember;
959
return propertyInfos;
962
public static BindingFlags RemoveFlag(this BindingFlags bindingAttr, BindingFlags flag)
964
return ((bindingAttr & flag) == flag)
969
private static void GetChildPrivateProperties(IList<PropertyInfo> initialProperties, Type targetType, BindingFlags bindingAttr)
971
// fix weirdness with private PropertyInfos only being returned for the current Type
972
// find base type properties and add them to result
973
if ((bindingAttr & BindingFlags.NonPublic) != 0)
975
// modify flags to not search for public fields
976
BindingFlags nonPublicBindingAttr = bindingAttr.RemoveFlag(BindingFlags.Public);
978
while ((targetType = targetType.BaseType()) != null)
980
foreach (PropertyInfo propertyInfo in targetType.GetProperties(nonPublicBindingAttr))
982
PropertyInfo nonPublicProperty = propertyInfo;
984
// have to test on name rather than reference because instances are different
985
// depending on the type that GetProperties was called on
986
int index = initialProperties.IndexOf(p => p.Name == nonPublicProperty.Name);
989
initialProperties.Add(nonPublicProperty);
993
// replace nonpublic properties for a child, but gotten from
994
// the parent with the one from the child
995
// the property gotten from the child will have access to private getter/setter
996
initialProperties[index] = nonPublicProperty;
1003
public static bool IsMethodOverridden(Type currentType, Type methodDeclaringType, string method)
1005
bool isMethodOverriden = currentType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
1007
info.Name == method &&
1008
// check that the method overrides the original on DynamicObjectProxy
1009
info.DeclaringType != methodDeclaringType
1010
// todo - find out whether there is a way to do this in winrt
1012
&& info.GetBaseDefinition().DeclaringType == methodDeclaringType
1016
return isMethodOverriden;
1019
public static object GetDefaultValue(Type type)
1021
if (!type.IsValueType())
1024
switch (ConvertUtils.GetTypeCode(type))
1026
case TypeCode.Boolean:
1029
case TypeCode.SByte:
1031
case TypeCode.Int16:
1032
case TypeCode.UInt16:
1033
case TypeCode.Int32:
1034
case TypeCode.UInt32:
1036
case TypeCode.Int64:
1037
case TypeCode.UInt64:
1039
case TypeCode.Single:
1041
case TypeCode.Double:
1043
case TypeCode.Decimal:
1045
case TypeCode.DateTime:
1046
return new DateTime();
1049
if (type == typeof(Guid))
1053
if (type == typeof(DateTimeOffset))
1054
return new DateTimeOffset();
1057
if (IsNullable(type))
1060
// possibly use IL initobj for perf here?
1061
return Activator.CreateInstance(type);
b'\\ No newline at end of file'