private static bool CheckDictionaryAccessors(TypeModel model, Type pair, Type value) { return(pair.IsGenericType && pair.GetGenericTypeDefinition() == model.MapType(typeof(KeyValuePair <,>)) && pair.GetGenericArguments()[1] == value); }
internal static Type GetListItemType(TypeModel model, Type listType) { if (listType == model.MapType(typeof(string)) || listType.IsArray || !model.MapType(typeof(IEnumerable)).IsAssignableFrom(listType)) { return(null); } BasicList candidates = new BasicList(); MethodInfo[] methods = listType.GetMethods(); for (int i = 0; i < methods.Length; i++) { MethodInfo method = methods[i]; if (!method.IsStatic && !(method.Name != "Add")) { ParameterInfo[] parameters = method.GetParameters(); Type paramType; if (parameters.Length == 1 && !candidates.Contains(paramType = parameters[0].ParameterType)) { candidates.Add(paramType); } } } string name = listType.Name; if (name == null || (name.IndexOf("Queue") < 0 && name.IndexOf("Stack") < 0)) { TypeModel.TestEnumerableListPatterns(model, candidates, listType); Type[] interfaces = listType.GetInterfaces(); for (int j = 0; j < interfaces.Length; j++) { Type iType = interfaces[j]; TypeModel.TestEnumerableListPatterns(model, candidates, iType); } } PropertyInfo[] properties = listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int k = 0; k < properties.Length; k++) { PropertyInfo indexer = properties[k]; if (!(indexer.Name != "Item") && !candidates.Contains(indexer.PropertyType)) { ParameterInfo[] args = indexer.GetIndexParameters(); if (args.Length == 1 && !(args[0].ParameterType != model.MapType(typeof(int)))) { candidates.Add(indexer.PropertyType); } } } switch (candidates.Count) { case 0: return(null); case 1: return((Type)candidates[0]); case 2: if (TypeModel.CheckDictionaryAccessors(model, (Type)candidates[0], (Type)candidates[1])) { return((Type)candidates[0]); } if (TypeModel.CheckDictionaryAccessors(model, (Type)candidates[1], (Type)candidates[0])) { return((Type)candidates[1]); } break; } return(null); }