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;
30
using Newtonsoft.Json.Utilities.LinqBridge;
35
namespace Newtonsoft.Json.Utilities
37
internal static class TypeExtensions
40
private static BindingFlags DefaultFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
42
public static MethodInfo GetGetMethod(this PropertyInfo propertyInfo)
44
return propertyInfo.GetGetMethod(false);
47
public static MethodInfo GetGetMethod(this PropertyInfo propertyInfo, bool nonPublic)
49
MethodInfo getMethod = propertyInfo.GetMethod;
50
if (getMethod != null && (getMethod.IsPublic || nonPublic))
56
public static MethodInfo GetSetMethod(this PropertyInfo propertyInfo)
58
return propertyInfo.GetSetMethod(false);
61
public static MethodInfo GetSetMethod(this PropertyInfo propertyInfo, bool nonPublic)
63
MethodInfo setMethod = propertyInfo.SetMethod;
64
if (setMethod != null && (setMethod.IsPublic || nonPublic))
70
public static bool IsSubclassOf(this Type type, Type c)
72
return type.GetTypeInfo().IsSubclassOf(c);
75
public static bool IsAssignableFrom(this Type type, Type c)
77
return type.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo());
81
public static MemberTypes MemberType(this MemberInfo memberInfo)
83
#if !(NETFX_CORE || PORTABLE)
84
return memberInfo.MemberType;
86
if (memberInfo is PropertyInfo)
87
return MemberTypes.Property;
88
else if (memberInfo is FieldInfo)
89
return MemberTypes.Field;
90
else if (memberInfo is EventInfo)
91
return MemberTypes.Event;
92
else if (memberInfo is MethodInfo)
93
return MemberTypes.Method;
95
return MemberTypes.Other;
99
public static bool ContainsGenericParameters(this Type type)
102
return type.ContainsGenericParameters;
104
return type.GetTypeInfo().ContainsGenericParameters;
108
public static bool IsInterface(this Type type)
111
return type.IsInterface;
113
return type.GetTypeInfo().IsInterface;
117
public static bool IsGenericType(this Type type)
120
return type.IsGenericType;
122
return type.GetTypeInfo().IsGenericType;
126
public static bool IsGenericTypeDefinition(this Type type)
129
return type.IsGenericTypeDefinition;
131
return type.GetTypeInfo().IsGenericTypeDefinition;
135
public static Type BaseType(this Type type)
138
return type.BaseType;
140
return type.GetTypeInfo().BaseType;
144
public static bool IsEnum(this Type type)
149
return type.GetTypeInfo().IsEnum;
153
public static bool IsClass(this Type type)
158
return type.GetTypeInfo().IsClass;
162
public static bool IsSealed(this Type type)
165
return type.IsSealed;
167
return type.GetTypeInfo().IsSealed;
172
public static PropertyInfo GetProperty(this Type type, string name, BindingFlags bindingFlags, object placeholder1, Type propertyType, IList<Type> indexParameters, object placeholder2)
174
IList<PropertyInfo> propertyInfos = type.GetProperties(bindingFlags);
176
return propertyInfos.Where(p =>
178
if (name != null && name != p.Name)
180
if (propertyType != null && propertyType != p.PropertyType)
182
if (indexParameters != null)
184
if (!p.GetIndexParameters().Select(ip => ip.ParameterType).SequenceEqual(indexParameters))
189
}).SingleOrDefault();
192
public static IEnumerable<MemberInfo> GetMember(this Type type, string name, MemberTypes memberType, BindingFlags bindingFlags)
194
return type.GetMembers(bindingFlags).Where(m =>
196
if (name != null && name != m.Name)
198
if (m.MemberType() != memberType)
207
public static bool IsDefined(this Type type, Type attributeType, bool inherit)
209
return type.GetTypeInfo().CustomAttributes.Any(a => a.AttributeType == attributeType);
212
public static MethodInfo GetMethod(this Type type, string name)
214
return type.GetMethod(name, DefaultFlags);
217
public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingFlags)
219
return type.GetTypeInfo().GetDeclaredMethod(name);
222
public static MethodInfo GetMethod(this Type type, IList<Type> parameterTypes)
224
return type.GetMethod(null, parameterTypes);
227
public static MethodInfo GetMethod(this Type type, string name, IList<Type> parameterTypes)
229
return type.GetMethod(name, DefaultFlags, null, parameterTypes, null);
232
public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingFlags, object placeHolder1, IList<Type> parameterTypes, object placeHolder2)
234
return type.GetTypeInfo().DeclaredMethods.Where(m =>
236
if (name != null && m.Name != name)
239
if (!TestAccessibility(m, bindingFlags))
242
return m.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes);
243
}).SingleOrDefault();
246
public static PropertyInfo GetProperty(this Type type, string name, BindingFlags bindingFlags, object placeholder1, Type propertyType, IList<Type> indexParameters, object placeholder2)
248
return type.GetTypeInfo().DeclaredProperties.Where(p =>
250
if (name != null && name != p.Name)
252
if (propertyType != null && propertyType != p.PropertyType)
254
if (indexParameters != null)
256
if (!p.GetIndexParameters().Select(ip => ip.ParameterType).SequenceEqual(indexParameters))
261
}).SingleOrDefault();
264
public static IEnumerable<MemberInfo> GetMember(this Type type, string name, MemberTypes memberType, BindingFlags bindingFlags)
266
return type.GetTypeInfo().GetMembersRecursive().Where(m =>
268
if (name != null && name != m.Name)
270
if (m.MemberType() != memberType)
272
if (!TestAccessibility(m, bindingFlags))
279
public static IEnumerable<ConstructorInfo> GetConstructors(this Type type)
281
return type.GetConstructors(DefaultFlags);
284
public static IEnumerable<ConstructorInfo> GetConstructors(this Type type, BindingFlags bindingFlags)
286
return type.GetConstructors(bindingFlags, null);
289
private static IEnumerable<ConstructorInfo> GetConstructors(this Type type, BindingFlags bindingFlags, IList<Type> parameterTypes)
291
return type.GetTypeInfo().DeclaredConstructors.Where(c =>
293
if (!TestAccessibility(c, bindingFlags))
296
if (parameterTypes != null && !c.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes))
303
public static ConstructorInfo GetConstructor(this Type type, IList<Type> parameterTypes)
305
return type.GetConstructor(DefaultFlags, null, parameterTypes, null);
308
public static ConstructorInfo GetConstructor(this Type type, BindingFlags bindingFlags, object placeholder1, IList<Type> parameterTypes, object placeholder2)
310
return type.GetConstructors(bindingFlags, parameterTypes).SingleOrDefault();
313
public static MemberInfo[] GetMember(this Type type, string member)
315
return type.GetMember(member, DefaultFlags);
318
public static MemberInfo[] GetMember(this Type type, string member, BindingFlags bindingFlags)
320
return type.GetTypeInfo().GetMembersRecursive().Where(m => m.Name == member && TestAccessibility(m, bindingFlags)).ToArray();
323
public static MemberInfo GetField(this Type type, string member)
325
return type.GetField(member, DefaultFlags);
328
public static MemberInfo GetField(this Type type, string member, BindingFlags bindingFlags)
330
return type.GetTypeInfo().GetDeclaredField(member);
333
public static IEnumerable<PropertyInfo> GetProperties(this Type type, BindingFlags bindingFlags)
335
return type.GetTypeInfo().GetPropertiesRecursive().Where(p => TestAccessibility(p, bindingFlags));
338
private static IList<MemberInfo> GetMembersRecursive(this TypeInfo type)
341
IList<MemberInfo> members = new List<MemberInfo>();
344
foreach (var member in t.DeclaredMembers)
346
if (!members.Any(p => p.Name == member.Name))
349
t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null;
355
private static IList<PropertyInfo> GetPropertiesRecursive(this TypeInfo type)
358
IList<PropertyInfo> properties = new List<PropertyInfo>();
361
foreach (var member in t.DeclaredProperties)
363
if (!properties.Any(p => p.Name == member.Name))
364
properties.Add(member);
366
t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null;
372
private static IList<FieldInfo> GetFieldsRecursive(this TypeInfo type)
375
IList<FieldInfo> fields = new List<FieldInfo>();
378
foreach (var member in t.DeclaredFields)
380
if (!fields.Any(p => p.Name == member.Name))
383
t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null;
389
public static IEnumerable<MethodInfo> GetMethods(this Type type, BindingFlags bindingFlags)
391
return type.GetTypeInfo().DeclaredMethods;
394
public static PropertyInfo GetProperty(this Type type, string name)
396
return type.GetProperty(name, DefaultFlags);
399
public static PropertyInfo GetProperty(this Type type, string name, BindingFlags bindingFlags)
401
return type.GetTypeInfo().GetDeclaredProperty(name);
404
public static IEnumerable<FieldInfo> GetFields(this Type type)
406
return type.GetFields(DefaultFlags);
409
public static IEnumerable<FieldInfo> GetFields(this Type type, BindingFlags bindingFlags)
411
return type.GetTypeInfo().GetFieldsRecursive().Where(f => TestAccessibility(f, bindingFlags)).ToList();
414
private static bool TestAccessibility(PropertyInfo member, BindingFlags bindingFlags)
416
if (member.GetMethod != null && TestAccessibility(member.GetMethod, bindingFlags))
419
if (member.SetMethod != null && TestAccessibility(member.SetMethod, bindingFlags))
425
private static bool TestAccessibility(MemberInfo member, BindingFlags bindingFlags)
427
if (member is FieldInfo)
429
return TestAccessibility((FieldInfo)member, bindingFlags);
431
else if (member is MethodBase)
433
return TestAccessibility((MethodBase)member, bindingFlags);
435
else if (member is PropertyInfo)
437
return TestAccessibility((PropertyInfo)member, bindingFlags);
440
throw new Exception("Unexpected member type.");
443
private static bool TestAccessibility(FieldInfo member, BindingFlags bindingFlags)
445
bool visibility = (member.IsPublic && bindingFlags.HasFlag(BindingFlags.Public)) ||
446
(!member.IsPublic && bindingFlags.HasFlag(BindingFlags.NonPublic));
448
bool instance = (member.IsStatic && bindingFlags.HasFlag(BindingFlags.Static)) ||
449
(!member.IsStatic && bindingFlags.HasFlag(BindingFlags.Instance));
451
return visibility && instance;
454
private static bool TestAccessibility(MethodBase member, BindingFlags bindingFlags)
456
bool visibility = (member.IsPublic && bindingFlags.HasFlag(BindingFlags.Public)) ||
457
(!member.IsPublic && bindingFlags.HasFlag(BindingFlags.NonPublic));
459
bool instance = (member.IsStatic && bindingFlags.HasFlag(BindingFlags.Static)) ||
460
(!member.IsStatic && bindingFlags.HasFlag(BindingFlags.Instance));
462
return visibility && instance;
465
public static Type[] GetGenericArguments(this Type type)
467
return type.GetTypeInfo().GenericTypeArguments;
470
public static IEnumerable<Type> GetInterfaces(this Type type)
472
return type.GetTypeInfo().ImplementedInterfaces;
475
public static IEnumerable<MethodInfo> GetMethods(this Type type)
477
return type.GetTypeInfo().DeclaredMethods;
481
public static bool IsAbstract(this Type type)
484
return type.IsAbstract;
486
return type.GetTypeInfo().IsAbstract;
490
public static bool IsVisible(this Type type)
493
return type.IsVisible;
495
return type.GetTypeInfo().IsVisible;
499
public static bool IsValueType(this Type type)
502
return type.IsValueType;
504
return type.GetTypeInfo().IsValueType;
508
public static bool AssignableToTypeName(this Type type, string fullTypeName, out Type match)
512
while (current != null)
514
if (string.Equals(current.FullName, fullTypeName, StringComparison.Ordinal))
520
current = current.BaseType();
523
foreach (Type i in type.GetInterfaces())
525
if (string.Equals(i.Name, fullTypeName, StringComparison.Ordinal))
536
public static bool AssignableToTypeName(this Type type, string fullTypeName)
539
return type.AssignableToTypeName(fullTypeName, out match);
542
public static MethodInfo GetGenericMethod(this Type type, string name, params Type[] parameterTypes)
544
var methods = type.GetMethods().Where(method => method.Name == name);
546
foreach (var method in methods)
548
if (method.HasParameters(parameterTypes))
555
public static bool HasParameters(this MethodInfo method, params Type[] parameterTypes)
557
var methodParameters = method.GetParameters().Select(parameter => parameter.ParameterType).ToArray();
559
if (methodParameters.Length != parameterTypes.Length)
562
for (int i = 0; i < methodParameters.Length; i++)
563
if (methodParameters[i].ToString() != parameterTypes[i].ToString())
569
public static IEnumerable<Type> GetAllInterfaces(this Type target)
571
foreach (var i in target.GetInterfaces())
574
foreach (var ci in i.GetInterfaces())
581
public static IEnumerable<MethodInfo> GetAllMethods(this Type target)
583
var allTypes = target.GetAllInterfaces().ToList();
584
allTypes.Add(target);
586
return from type in allTypes
587
from method in type.GetMethods()
b'\\ No newline at end of file'