【问题标题】:Determine if two methods have the same base definition确定两个方法是否具有相同的基本定义
【发布时间】:2011-05-09 18:41:51
【问题描述】:

我刚刚不幸(至少对我的应用程序而言)发现在泛型类中声明的两个方法没有相同的基本定义,这在代码中得到了最好的证明:

    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(),但是如何处理泛型类中声明的方法?

【问题讨论】:

  • 您不只是请求查看 MethodsCollection 是否包含对所选 MethodInfo 的引用吗?也许是一个用例来说明这在什么时候有用?
  • 模板的两种实现之间的类型不同的事实意味着它们在定义上是不同的。您说您想查看它们是否定义在同一个类中,但 Generic 与 Generic 并不完全相同。
  • @James (/Tejs),不幸的是,他们在同一个班级中被宣布对我来说意义重大。基本上,我希望能够知道两个类(每个类共享一堆属性)是否有任何共同的部分——以允许将设置从一个类复制到另一个类。这不仅适用于任何课程 - 我确实可以控制课程并且仅供内部使用,但知道它会非常有用。属性使事情进一步复杂化,所以我很高兴将问题留在方法上;)。目前这一切都运作良好,直到涉及到泛型我可能会添加..

标签: c# .net generics reflection


【解决方案1】:

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

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

【讨论】:

  • 我真的希望不要诉诸于通过名称解析方法,我在示例中意识到 - 但在真正的应用程序中,我已经拥有了两个 MethodInfos。在重载和属性隐藏(使用 new 运算符)等存在的情况下抓住他们的名字并搜索他们会对我造成破坏。我对 AmbiguousMatchException 太熟悉了..
  • 你应该澄清这个问题......我只是让你失败的测试通过
  • @robert - 已更新。您更新的解决方案对于在同一个泛型类中声明的任何两个方法都返回 true,不幸的是没有好处。在最初的帖子中,我提出了 + 名称检查,但是由于重载而失败:(。
  • @mania - 为您处理特定重载检查的又一更新
  • @罗伯特问候。名称,类型和参数..为了更好的衡量,我可能也会检查返回,以防我使用来自某种曲线球语言或混淆器的类,但这确实是我真正需要的:)。谢谢。
猜你喜欢
  • 1970-01-01
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-15
  • 1970-01-01
  • 2019-11-08
相关资源
最近更新 更多