internal static ChainedExtension FindNextImplementation(Type type, ChainedExtension next) { if (next == null) { return(null); } if (!type.IsInstanceOfType(next)) { return(FindNextImplementation(type, next.nextInChain)); } foreach (var m in type.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { MethodInfo method = m as MethodInfo; if (method == null) { var prop = m as PropertyInfo; if (prop != null) { method = prop.GetGetMethod(); if (method == null) { method = prop.GetSetMethod(); } } } if (method != null && method.IsVirtual && method.Name != "InitializeChain") { var tm = next.GetType().GetMethod(method.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, method.GetParameters().Select(p => p.ParameterType).ToArray(), null); if (tm == null) { continue; } if (tm.DeclaringType != type) { return(next); } } } // Serializable fields and properties if (next.GetType().GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Any(m => m.IsDefined(typeof(MonoDevelop.Core.Serialization.ItemPropertyAttribute)))) { return(next); } return(FindNextImplementation(type, next.nextInChain)); }
static ChainedExtension FindNextImplementation_Internal(Type type, ChainedExtension next, ref int position) { if (next == null) { return(null); } position++; if (!type.IsInstanceOfType(next)) { return(FindNextImplementation_Internal(type, next.nextInChain, ref position)); } // Maybe it would make sense to cache these, but not sure if we should. foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (method != null && method.IsVirtual && method.Name != "InitializeChain") { var paramArray = method.GetParameters(); var paramTypeArray = new Type [paramArray.Length]; for (int i = 0; i < paramArray.Length; ++i) { paramTypeArray [i] = paramArray [i].ParameterType; } var tm = next.GetType().GetMethod(method.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, paramTypeArray, null); if (tm == null) { continue; } if (tm.DeclaringType != type) { return(next); } } } // Serializable fields and properties foreach (var m in next.GetType().GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (m.IsDefined(typeof(MonoDevelop.Core.Serialization.ItemPropertyAttribute))) { return(next); } } return(FindNextImplementation_Internal(type, next.nextInChain, ref position)); }