예제 #1
0
        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));
        }
예제 #2
0
        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));
        }