private static bool HasCast(Type type, Type from, Type to, out MethodInfo op) { #if WINRT System.Collections.Generic.List <MethodInfo> list = new System.Collections.Generic.List <MethodInfo>(); foreach (var item in type.GetRuntimeMethods()) { if (item.IsStatic) { list.Add(item); } } MethodInfo[] found = list.ToArray(); #else const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo[] found = type.GetMethods(flags); #endif for (int i = 0; i < found.Length; i++) { MethodInfo m = found[i]; if ((m.Name != "op_Implicit" && m.Name != "op_Explicit") || m.ReturnType != to) { continue; } ParameterInfo[] paramTypes = m.GetParameters(); if (paramTypes.Length == 1 && paramTypes[0].ParameterType == from) { op = m; return(true); } } op = null; return(false); }
private CilType ProcessType(IKVM.Reflection.Type type) { var result = new CilType { Name = type.Name, Namespace = type.Namespace, BaseType = type.BaseType != null ? type.BaseType.FullName : null, ReflectionType = type }; var methods = new List <CilMethod>(); result.Methods = methods; var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; foreach (var method in type.GetMethods(flags)) { if (method.DeclaringType == type) { methods.Add(ProcessMethod(result, method)); } } foreach (var ctor in type.GetConstructors(flags)) { if (ctor.DeclaringType == type) { methods.Add(ProcessMethod(result, ctor)); } } return(result); }
public static ParseableSerializer TryCreate(Type type, TypeModel model) { if (type == null) throw new ArgumentNullException("type"); #if WINRT || PORTABLE || COREFX MethodInfo method = null; #if WINRT || COREFX foreach (MethodInfo tmp in type.GetTypeInfo().GetDeclaredMethods("Parse")) #else foreach (MethodInfo tmp in type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) #endif { ParameterInfo[] p; if (tmp.Name == "Parse" && tmp.IsPublic && tmp.IsStatic && tmp.DeclaringType == type && (p = tmp.GetParameters()) != null && p.Length == 1 && p[0].ParameterType == typeof(string)) { method = tmp; break; } } #else MethodInfo method = type.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly, null, new Type[] { model.MapType(typeof(string)) }, null); #endif if (method != null && method.ReturnType == type) { if (Helpers.IsValueType(type)) { MethodInfo toString = GetCustomToString(type); if (toString == null || toString.ReturnType != model.MapType(typeof(string))) return null; // need custom ToString, fools } return new ParseableSerializer(method); } return null; }
private static bool HasCast(Type type, Type from, Type to, out MethodInfo op) { #if WINRT System.Collections.Generic.List<MethodInfo> list = new System.Collections.Generic.List<MethodInfo>(); foreach (var item in type.GetRuntimeMethods()) { if (item.IsStatic) list.Add(item); } MethodInfo[] found = list.ToArray(); #else const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo[] found = type.GetMethods(flags); #endif for(int i = 0 ; i < found.Length ; i++) { MethodInfo m = found[i]; if ((m.Name != "op_Implicit" && m.Name != "op_Explicit") || m.ReturnType != to) { continue; } ParameterInfo[] paramTypes = m.GetParameters(); if(paramTypes.Length == 1 && paramTypes[0].ParameterType == from) { op = m; return true; } } op = null; return false; }
static InterlockedMethods() { #if !WINRT Type type = JVM.Import(typeof(System.Threading.Interlocked)); AddInt32 = type.GetMethod("Add", new Type[] { Types.Int32.MakeByRefType(), Types.Int32 }); CompareExchangeInt32 = type.GetMethod("CompareExchange", new Type[] { Types.Int32.MakeByRefType(), Types.Int32, Types.Int32 }); CompareExchangeInt64 = type.GetMethod("CompareExchange", new Type[] { Types.Int64.MakeByRefType(), Types.Int64, Types.Int64 }); foreach (MethodInfo m in type.GetMethods()) { if (m.IsGenericMethodDefinition) { switch (m.Name) { case "CompareExchange": CompareExchangeOfT = m; break; case "Exchange": ExchangeOfT = m; break; } } } #else throw new NotImplementedException(); #endif }
internal static MethodInfo GetStaticMethod(Type declaringType, string name) { foreach (MethodInfo method in declaringType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) { if (method.Name == name) return method; } return null; }
internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] parameterTypes) { foreach (MethodInfo method in declaringType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (method.Name == name && IsMatch(method.GetParameters(), parameterTypes)) return method; } return null; }
private static bool HasCast(TypeModel model, Type type, Type from, Type to, out MethodInfo op) { #if WINRT System.Collections.Generic.List<MethodInfo> list = new System.Collections.Generic.List<MethodInfo>(); foreach (var item in type.GetRuntimeMethods()) { if (item.IsStatic) list.Add(item); } MethodInfo[] found = list.ToArray(); #else const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo[] found = type.GetMethods(flags); #endif ParameterInfo[] paramTypes; Type convertAttributeType = null; for (int i = 0; i < found.Length; i++) { MethodInfo m = found[i]; if (m.ReturnType != to) continue; paramTypes = m.GetParameters(); if(paramTypes.Length == 1 && paramTypes[0].ParameterType == from) { if (convertAttributeType == null) { convertAttributeType = model.MapType(typeof(ProtoConverterAttribute), false); if (convertAttributeType == null) { // attribute isn't defined in the source assembly: stop looking break; } } if (m.IsDefined(convertAttributeType, true)) { op = m; return true; } } } for(int i = 0 ; i < found.Length ; i++) { MethodInfo m = found[i]; if ((m.Name != "op_Implicit" && m.Name != "op_Explicit") || m.ReturnType != to) { continue; } paramTypes = m.GetParameters(); if(paramTypes.Length == 1 && paramTypes[0].ParameterType == from) { op = m; return true; } } op = null; return false; }
internal static MethodInfo GetStaticMethod(Type declaringType, string name, Type[] parameterTypes) { foreach (MethodInfo method in declaringType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) { if (method.Name == name && IsMatch(method.GetParameters(), parameterTypes)) { return(method); } } return(null); }
internal static MethodInfo GetInstanceMethod(Type declaringType, string name) { foreach (MethodInfo method in declaringType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (method.Name == name) { return(method); } } return(null); }
private static bool HasCast(TypeModel model, Type type, Type from, Type to, out MethodInfo op) { #if WINRT System.Collections.Generic.List <MethodInfo> list = new System.Collections.Generic.List <MethodInfo>(); foreach (var item in type.GetRuntimeMethods()) { if (item.IsStatic) { list.Add(item); } } MethodInfo[] found = list.ToArray(); #else const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo[] found = type.GetMethods(flags); #endif ParameterInfo[] paramTypes; for (int i = 0; i < found.Length; i++) { MethodInfo m = found[i]; if (m.ReturnType != to) { continue; } paramTypes = m.GetParameters(); if (paramTypes.Length == 1 && paramTypes[0].ParameterType == from) { if (AttributeMap.GetAttribute(AttributeMap.Create(model, m, false), "ProtoBuf.ProtoConverterAttribute") != null || AttributeMap.GetAttribute(AttributeMap.Create(model, m, false), "AqlaSerializer.SurrogateConverterAttribute") != null) { op = m; return(true); } } } for (int i = 0; i < found.Length; i++) { MethodInfo m = found[i]; if ((m.Name != "op_Implicit" && m.Name != "op_Explicit") || m.ReturnType != to) { continue; } paramTypes = m.GetParameters(); if (paramTypes.Length == 1 && paramTypes[0].ParameterType == from) { op = m; return(true); } } op = null; return(false); }
internal static MethodInfo GetStaticMethod(Type declaringType, string name, Type[] parameterTypes) { #if PORTABLE foreach (MethodInfo method in declaringType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) { if (method.Name == name && IsMatch(method.GetParameters(), parameterTypes)) return method; } return null; #else return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null); #endif }
bool TryGetImplementedMethod(Type type, string name, Type[] paramTypes, out MethodInfo result) { var dotName = "." + name; foreach (var m in type.GetMethods(_memberFlags)) { if (!m.Name.EndsWith(dotName)) continue; result = type.GetMethod(m.Name, _memberFlags, _binder, paramTypes, null); if (result != null) return true; } return TryGetInterfaceMethod(type, name, paramTypes, out result); }
void FindInheritedInterfaceMethods(Type type, HashSet <string> masters, HashSet <MethodInfo> result) { if (!type.IsTypeBuilder()) { foreach (var i in type.GetInterfaces()) { FindInheritedInterfaceMethods(i, masters, result); } foreach (var mi in type.GetMethods()) { var master = mi.GetReflectedName(); if (mi.DeclaringType == type && !masters.Contains(master)) { result.Add(mi); masters.Add(master); } } } else if (type.IsGenericType) { var def = type.GetGenericTypeDefinition(); foreach (var i in def.GetInterfaces()) { FindInheritedInterfaceMethods(ParameterizeInterface(type, i), masters, result); } foreach (var mi in def.GetMethods()) { var master = mi.GetReflectedName(); if (mi.DeclaringType == def && !masters.Contains(master)) { result.Add(TypeBuilder.GetMethod(type, mi)); masters.Add(master); } } } }
protected IEnumerable <MethodInfo> GetMethods(Type t) { foreach (var mi in t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)) { if (!mi.IsPublic) { continue; } var rt = mi.ReturnType; if (!IsSupported(rt)) { delayed.Add(ErrorHelper.CreateWarning(1030, $"Method `{mi}` is not generated because return type `{rt}` is not supported.")); continue; } bool pcheck = true; foreach (var p in mi.GetParameters()) { var pt = p.ParameterType; if (!IsSupported(pt)) { delayed.Add(ErrorHelper.CreateWarning(1031, $"Method `{mi}` is not generated because of parameter type `{pt}` is not supported.")); pcheck = false; } else if (p.HasDefaultValue) { delayed.Add(ErrorHelper.CreateWarning(1032, $"Method `{mi}` parameter `{p.Name}` has a default value that is not supported.")); } } if (!pcheck) { continue; } yield return(mi); } }
private static bool HasCast(TypeModel model, Type type, Type from, Type to, out MethodInfo op) { #if WINRT System.Collections.Generic.List <MethodInfo> list = new System.Collections.Generic.List <MethodInfo>(); foreach (var item in type.GetRuntimeMethods()) { if (item.IsStatic) { list.Add(item); } } MethodInfo[] found = list.ToArray(); #else const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo[] found = type.GetMethods(flags); #endif ParameterInfo[] paramTypes; Type convertAttributeType = null; for (int i = 0; i < found.Length; i++) { MethodInfo m = found[i]; if (m.ReturnType != to) { continue; } paramTypes = m.GetParameters(); if (paramTypes.Length == 1 && paramTypes[0].ParameterType == from) { if (convertAttributeType == null) { convertAttributeType = model.MapType(typeof(ProtoConverterAttribute), false); if (convertAttributeType == null) { // attribute isn't defined in the source assembly: stop looking break; } } if (m.IsDefined(convertAttributeType, true)) { op = m; return(true); } } } for (int i = 0; i < found.Length; i++) { MethodInfo m = found[i]; if ((m.Name != "op_Implicit" && m.Name != "op_Explicit") || m.ReturnType != to) { continue; } paramTypes = m.GetParameters(); if (paramTypes.Length == 1 && paramTypes[0].ParameterType == from) { op = m; return(true); } } op = null; return(false); }
protected IEnumerable <MethodInfo> GetMethods(Type t) { foreach (var mi in t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)) { if (!mi.IsPublic) { continue; } // handle special cases where we can implement something better, e.g. a better match if (implement_system_icomparable_t) { // for X we prefer `IComparable<X>` to `IComparable` - since it will be exposed identically to ObjC if (mi.Match("System.Int32", "CompareTo", t.FullName)) { icomparable [t] = mi; continue; } } if (implement_system_icomparable && mi.Match("System.Int32", "CompareTo", "System.Object")) { // don't replace CompareTo(T) with CompareTo(Object) if (!icomparable.ContainsKey(t)) { icomparable.Add(t, mi); } continue; } if (mi.Match("System.Boolean", "Equals", "System.Object")) { equals.Add(t, mi); continue; } if (mi.Match("System.Int32", "GetHashCode")) { hashes.Add(t, mi); continue; } var rt = mi.ReturnType; if (!IsSupported(rt)) { delayed.Add(ErrorHelper.CreateWarning(1030, $"Method `{mi}` is not generated because return type `{rt}` is not supported.")); continue; } bool pcheck = true; foreach (var p in mi.GetParameters()) { var pt = p.ParameterType; if (!IsSupported(pt)) { delayed.Add(ErrorHelper.CreateWarning(1031, $"Method `{mi}` is not generated because of parameter type `{pt}` is not supported.")); pcheck = false; } else if (p.HasDefaultValue) { members_with_default_values.Add(mi); } } if (!pcheck) { continue; } // handle extension methods if (extension_type && mi.HasCustomAttribute("System.Runtime.CompilerServices", "ExtensionAttribute")) { var extended_type = mi.GetParameters() [0].ParameterType; if (extended_type.IsPrimitive) { delayed.Add(ErrorHelper.CreateWarning(1034, $"Extension method `{mi}` is not generated inside a category because they cannot be created on primitive type `{extended_type}`. A normal, static method was generated.")); } else { Dictionary <Type, List <MethodInfo> > extensions; if (!extensions_methods.TryGetValue(t, out extensions)) { extensions = new Dictionary <Type, List <MethodInfo> > (); extensions_methods.Add(t, extensions); } List <MethodInfo> extmethods; if (!extensions.TryGetValue(extended_type, out extmethods)) { extmethods = new List <MethodInfo> (); extensions.Add(extended_type, extmethods); } extmethods.Add(mi); continue; } } yield return(mi); } }
internal static bool IdentifyImmutable(TypeModel model, Type declaredType, out MethodInfo builderFactory, out MethodInfo add, out MethodInfo addRange, out MethodInfo finish) { builderFactory = add = addRange = finish = null; if (model == null || declaredType == null) { return(false); } #if WINRT || COREFX TypeInfo declaredTypeInfo = declaredType.GetTypeInfo(); #else Type declaredTypeInfo = declaredType; #endif // try to detect immutable collections; firstly, they are all generic, and all implement IReadOnlyCollection<T> for some T if (!declaredTypeInfo.IsGenericType) { return(false); } #if WINRT || COREFX Type[] typeArgs = declaredTypeInfo.GenericTypeArguments, effectiveType; #else Type[] typeArgs = declaredTypeInfo.GetGenericArguments(), effectiveType; #endif switch (typeArgs.Length) { case 1: effectiveType = typeArgs; break; // fine case 2: Type kvp = model.MapType(typeof(System.Collections.Generic.KeyValuePair <,>)); if (kvp == null) { return(false); } kvp = kvp.MakeGenericType(typeArgs); effectiveType = new Type[] { kvp }; break; default: return(false); // no clue! } if (ResolveIReadOnlyCollection(declaredType, null) == null) { return(false); // no IReadOnlyCollection<T> found } // and we want to use the builder API, so for generic Foo<T> or IFoo<T> we want to use Foo.CreateBuilder<T> string name = declaredType.Name; int i = name.IndexOf('`'); if (i <= 0) { return(false); } name = declaredTypeInfo.IsInterface ? name.Substring(1, i - 1) : name.Substring(0, i); Type outerType = model.GetType(declaredType.Namespace + "." + name, declaredTypeInfo.Assembly); // I hate special-cases... if (outerType == null && name == "ImmutableSet") { outerType = model.GetType(declaredType.Namespace + ".ImmutableHashSet", declaredTypeInfo.Assembly); } if (outerType == null) { return(false); } #if WINRT foreach (MethodInfo method in outerType.GetTypeInfo().DeclaredMethods) #else foreach (MethodInfo method in outerType.GetMethods()) #endif { if (!method.IsStatic || method.Name != "CreateBuilder" || !method.IsGenericMethodDefinition || method.GetParameters().Length != 0 || method.GetGenericArguments().Length != typeArgs.Length) { continue; } builderFactory = method.MakeGenericMethod(typeArgs); break; } Type voidType = model.MapType(typeof(void)); if (builderFactory == null || builderFactory.ReturnType == null || builderFactory.ReturnType == voidType) { return(false); } add = Helpers.GetInstanceMethod(builderFactory.ReturnType, "Add", effectiveType); if (add == null) { return(false); } finish = Helpers.GetInstanceMethod(builderFactory.ReturnType, "ToImmutable", Helpers.EmptyTypes); if (finish == null || finish.ReturnType == null || finish.ReturnType == voidType) { return(false); } if (!(finish.ReturnType == declaredType || Helpers.IsAssignableFrom(declaredType, finish.ReturnType))) { return(false); } addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] { declaredType }); if (addRange == null) { Type enumerable = model.MapType(typeof(System.Collections.Generic.IEnumerable <>), false); if (enumerable != null) { addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] { enumerable.MakeGenericType(effectiveType) }); } } return(true); }
public void OutlineType() { bool first; OutlineAttributes(); o.Write(GetTypeVisibility(t)); if (t.IsClass && !t.IsSubclassOf(type_multicast_delegate)) { if (t.IsSealed) { o.Write(t.IsAbstract ? " static" : " sealed"); } else if (t.IsAbstract) { o.Write(" abstract"); } } o.Write(" "); o.Write(GetTypeKind(t)); o.Write(" "); Type [] interfaces = (Type [])Comparer.Sort(TypeGetInterfaces(t, declared_only)); Type parent = t.BaseType; if (t.IsSubclassOf(type_multicast_delegate)) { MethodInfo method; method = t.GetMethod("Invoke"); o.Write(FormatType(method.ReturnType)); o.Write(" "); o.Write(GetTypeName(t)); o.Write(" ("); OutlineParams(method.GetParameters()); o.Write(")"); WriteGenericConstraints(t.GetGenericArguments()); o.WriteLine(";"); return; } o.Write(GetTypeName(t)); if (((parent != null && parent != type_object && parent != type_value_type) || interfaces.Length != 0) && !t.IsEnum) { first = true; o.Write(" : "); if (parent != null && parent != type_object && parent != type_value_type) { o.Write(FormatType(parent)); first = false; } foreach (Type intf in interfaces) { if (!first) { o.Write(", "); } first = false; o.Write(FormatType(intf)); } } if (t.IsEnum) { Type underlyingType = t.GetEnumUnderlyingType(); if (underlyingType != type_int) { o.Write(" : {0}", FormatType(underlyingType)); } } WriteGenericConstraints(t.GetGenericArguments()); o.WriteLine(" {"); o.Indent++; if (t.IsEnum) { bool is_first = true; foreach (FieldInfo fi in t.GetFields(BindingFlags.Public | BindingFlags.Static)) { if (!is_first) { o.WriteLine(","); } is_first = false; o.Write(fi.Name); } o.WriteLine(); o.Indent--; o.WriteLine("}"); return; } first = true; foreach (ConstructorInfo ci in t.GetConstructors(DefaultFlags)) { if (!ShowMember(ci)) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(ci); OutlineConstructor(ci); o.WriteLine(); } first = true; foreach (MethodInfo m in Comparer.Sort(t.GetMethods(DefaultFlags))) { if (!ShowMember(m)) { continue; } if ((m.Attributes & MethodAttributes.SpecialName) != 0) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(m); OutlineMethod(m); o.WriteLine(); } first = true; foreach (MethodInfo m in t.GetMethods(DefaultFlags)) { if (!ShowMember(m)) { continue; } if ((m.Attributes & MethodAttributes.SpecialName) == 0) { continue; } if (!(m.Name.StartsWith("op_"))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(m); OutlineOperator(m); o.WriteLine(); } first = true; foreach (PropertyInfo pi in Comparer.Sort(t.GetProperties(DefaultFlags))) { if (!((pi.CanRead && ShowMember(pi.GetGetMethod(true))) || (pi.CanWrite && ShowMember(pi.GetSetMethod(true))))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(pi); OutlineProperty(pi); o.WriteLine(); } first = true; foreach (FieldInfo fi in t.GetFields(DefaultFlags)) { if (!ShowMember(fi)) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(fi); OutlineField(fi); o.WriteLine(); } first = true; foreach (EventInfo ei in Comparer.Sort(t.GetEvents(DefaultFlags))) { if (!ShowMember(ei.GetAddMethod(true))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(ei); OutlineEvent(ei); o.WriteLine(); } first = true; foreach (Type ntype in Comparer.Sort(t.GetNestedTypes(DefaultFlags))) { if (!ShowMember(ntype)) { continue; } if (first) { o.WriteLine(); } first = false; #if STATIC new Outline(universe, mscorlib, ntype, o, declared_only, show_private, filter_obsolete).OutlineType(); #else new Outline(ntype, o, declared_only, show_private, filter_obsolete).OutlineType(); #endif } o.Indent--; o.WriteLine("}"); }
internal static Type GetListItemType(TypeModel model, Type listType) { Helpers.DebugAssert(listType != null); #if WINRT TypeInfo listTypeInfo = listType.GetTypeInfo(); if (listType == typeof(string) || listType.IsArray || !typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(listTypeInfo)) { return(null); } #else if (listType == model.MapType(typeof(string)) || listType.IsArray || !model.MapType(typeof(IEnumerable)).IsAssignableFrom(listType)) { return(null); } #endif BasicList candidates = new BasicList(); #if WINRT foreach (MethodInfo method in listType.GetRuntimeMethods()) #else foreach (MethodInfo method in listType.GetMethods()) #endif { if (method.IsStatic || method.Name != "Add") { continue; } ParameterInfo[] parameters = method.GetParameters(); Type paramType; if (parameters.Length == 1 && !candidates.Contains(paramType = parameters[0].ParameterType)) { candidates.Add(paramType); } } string name = listType.Name; bool isQueueStack = name != null && (name.IndexOf("Queue", System.StringComparison.Ordinal) >= 0 || name.IndexOf("Stack", System.StringComparison.Ordinal) >= 0); #if !NO_GENERICS if (!isQueueStack) { TestEnumerableListPatterns(model, candidates, listType); #if WINRT foreach (Type iType in listTypeInfo.ImplementedInterfaces) { TestEnumerableListPatterns(model, candidates, iType); } #else foreach (Type iType in listType.GetInterfaces()) { TestEnumerableListPatterns(model, candidates, iType); } #endif } #endif #if WINRT // more convenient GetProperty overload not supported on all platforms foreach (PropertyInfo indexer in listType.GetRuntimeProperties()) { if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) { continue; } ParameterInfo[] args = indexer.GetIndexParameters(); if (args.Length != 1 || args[0].ParameterType != typeof(int)) { continue; } MethodInfo getter = indexer.GetMethod; if (getter == null || getter.IsStatic) { continue; } candidates.Add(indexer.PropertyType); } #else // more convenient GetProperty overload not supported on all platforms foreach (PropertyInfo indexer in listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) { continue; } ParameterInfo[] args = indexer.GetIndexParameters(); if (args.Length != 1 || args[0].ParameterType != model.MapType(typeof(int))) { continue; } candidates.Add(indexer.PropertyType); } #endif switch (candidates.Count) { case 0: return(null); case 1: return((Type)candidates[0]); case 2: if (CheckDictionaryAccessors(model, (Type)candidates[0], (Type)candidates[1])) { return((Type)candidates[0]); } if (CheckDictionaryAccessors(model, (Type)candidates[1], (Type)candidates[0])) { return((Type)candidates[1]); } break; } return(null); }