Определите, имеют ли два метода одинаковое базовое определение - PullRequest
2 голосов
/ 09 мая 2011

Я только что сделал неудачное (по крайней мере для моего приложения) открытие, что два метода, объявленные внутри универсального класса, не имеют одинакового базового определения, продемонстрированного лучше всего в коде:

    public static class Test
    {
        private class Generic<T> { public void Method() { } }
        public static void TestBase()
        {
            var x = typeof(Generic<int>).GetMethod("Method");
            var y = typeof(Generic<double>).GetMethod("Method");
            Debug.Assert(x.GetBaseDefinition() == y.GetBaseDefinition()); // fails
        }
    }

И x, и y.IsGeneric имеют значение false, поэтому GetGenericMethodDefinition использовать нельзя.

Единственное решение, которое я смог придумать до сих пор, - это сравнить их имена и то, что их декларирующие типы имеют один и тот же универсальный тип, но при наличии перегрузок, которые кажутся очень хрупкими

Итак ... я не думаю, что есть какой-то полезный метод, который я пропустил в библиотеке отражений, который может сказать мне, были ли эти два метода впервые объявлены в одном и том же классе? Или обходной путь?

EDIT:

Чтобы уточнить, я хочу сделать метод:

    public bool DeclaredInSameClass(MethodInfo a, MethodInfo b);

, который возвращает true, если оба a и b оба впервые объявлены в одном и том же классе.

Игнорирование обобщений, это просто: a.GetBaseDefinition() == y.GetBaseDefinition(), но как обращаться с методами, объявленными в обобщенных классах?

1 Ответ

5 голосов
/ 09 мая 2011

РЕДАКТИРОВАТЬ ... последняя попытка:

    private class Generic<T> { 
        public void Method() { }
        public void Method(string param) { }
        public void OtherMethod() { }  
    }
    private class NonGeneric { public void Method() { } }
    static void Main(string[] args)
    {
        var x = typeof(Generic<int>).GetMethod("Method", new Type[]{});
        var y = typeof(Generic<double>).GetMethod("Method", new Type[]{});
        var a = typeof(Generic<double>).GetMethod("OtherMethod");
        var b = typeof(NonGeneric).GetMethod("Method");
        var c = typeof(Generic<int>).GetMethod("Method", new Type[] { typeof(string) });

        Debug.Assert(DeclaredInSameClass(x, y));
        Debug.Assert(!DeclaredInSameClass(x, a));
        Debug.Assert(!DeclaredInSameClass(x, b));
        Debug.Assert(!DeclaredInSameClass(x, c));
        Debug.Assert(!DeclaredInSameClass(a, b));

    }

    public static bool DeclaredInSameClass(MethodInfo a, MethodInfo b)
    {
        if (a.DeclaringType.IsGenericType != b.DeclaringType.IsGenericType)
        {
            return false;
        }
        else if (a.DeclaringType.IsGenericType)
        {

            var x = a.DeclaringType.GetGenericTypeDefinition().GetMethod(a.Name, a.GetParameters().Select(p => p.ParameterType).ToArray());
            var y = b.DeclaringType.GetGenericTypeDefinition().GetMethod(b.Name, b.GetParameters().Select(p => p.ParameterType).ToArray());
            return x.Equals(y);
        }
        return a.GetBaseDefinition().Equals(b.GetBaseDefinition());
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...