确定两个方法是否具有相同的基本定义

时间:2011-05-09 18:41:52

标签: c# .net generics reflection

我刚刚发现不幸(至少对于我的应用程序)发现在泛型类中声明的两个方法没有相同的基本定义,在代码中表现最佳:

    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。

到目前为止,我能够想到的唯一解决方案是比较它们的名称,并且它们的声明类型是相同的泛型类型,但是存在看似非常脆弱的重载...

所以..我不认为我在反射库中错过了一个有用的方法,可以告诉我这两个方法是否已在同一个类中首次声明?或者解决方法?

编辑:

为了澄清,我想制作一个方法:

    public bool DeclaredInSameClass(MethodInfo a, MethodInfo b);

如果a和b都在同一个类中首次声明,则返回true。

忽略泛型,这很简单:a.GetBaseDefinition() == y.GetBaseDefinition(),但是如何处理泛型类中声明的方法?

1 个答案:

答案 0 :(得分:5)

编辑......最后一次尝试:

    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());
    }