private static object GetInstanceOfStep(string step, object instance) { Type type = instance.GetType(); if (step.StartsWith("[", StringComparison.InvariantCulture) && step.EndsWith("]", StringComparison.InvariantCulture)) { int index; string indexStr = step.Substring(1, step.Length - 2); if (!int.TryParse(indexStr, out index)) { throw new ArgumentException("Couldn't parse an index from the path step '" + step + "'."); } // We need to check the current type to see if we can treat it as a list if (type.IsArray) { Array array = (Array)instance; if (index < 0 || index >= array.Length) { return(null); } return(array.GetValue(index)); } else if (typeof(IList).IsAssignableFrom(type)) { IList list = (IList)instance; if (index < 0 || index >= list.Count) { return(null); } return(list[index]); } else if (type.ImplementsOpenGenericInterface(typeof(IList <>))) { Type elementType = type.GetArgumentsOfInheritedOpenGenericInterface(typeof(IList <>))[0]; Type listType = typeof(IList <>).MakeGenericType(elementType); MethodInfo getItemMethod = listType.GetMethod("get_Item", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); try { return(getItemMethod.Invoke(instance, new object[] { index })); } catch (Exception) { return(null); } } } else if (step.StartsWith("{", StringComparison.InvariantCultureIgnoreCase) && step.EndsWith("}", StringComparison.InvariantCultureIgnoreCase)) { if (type.ImplementsOpenGenericInterface(typeof(IDictionary <,>))) { var dictArgs = type.GetArgumentsOfInheritedOpenGenericInterface(typeof(IDictionary <,>)); object key = DictionaryKeyUtility.GetDictionaryKeyValue(step, dictArgs[0]); Type dictType = typeof(IDictionary <,>).MakeGenericType(dictArgs); MethodInfo getItemMethod = dictType.GetMethod("get_Item", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); try { return(getItemMethod.Invoke(instance, new object[] { key })); } catch (Exception) { return(null); } } } else { string privateTypeName = null; int plusIndex = step.IndexOf('+'); if (plusIndex >= 0) { privateTypeName = step.Substring(0, plusIndex); step = step.Substring(plusIndex + 1); } var possibleMembers = type.GetAllMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(n => n is FieldInfo || n is PropertyInfo); foreach (var member in possibleMembers) { if (member.Name == step) { if (privateTypeName != null && member.DeclaringType.Name != privateTypeName) { continue; } return(member.GetMemberValue(instance)); } } } return(null); }