2011-05-09 41 views
2

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

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

+0

难道你不只是要求,看看是否MethodsCollection包含于所选的MethodInfo的参考?也许是一个用例来说明什么时候这会有用? – Tejs 2011-05-09 19:14:31

+0

模板的两种实现之间的类型不同的事实意味着它们根据定义是不同的。你说你想看看它们是否在同一个班级中定义,但是通用与通用不同。 – 2011-05-09 19:18:43

+0

@ James(/ Tejs),不幸的是,他们在同一个班上宣布对我来说意义重大。基本上我希望能够知道两个共享一堆属性的类是否有任何共同的部分 - 允许将设置从一个类复制到另一个类。这不仅适用于任何类 - 我确实拥有对类的控制权,而且仅供内部使用,但它对于了解这些内容非常有用。尽管如此,属性使事情变得更复杂,所以我很乐意将问题留在方法上;)。这一切都工作得很好,直到泛型涉足我可能会添加.. – Mania 2011-05-09 19:27:03

回答

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

我真的希望不诉诸解决方法的名称,我意识到在我做的例子 - 但在真正的应用程序,我已经有两个MethodInfos。抓住他们的名字,并在存在重载和财产隐藏(与新操作员)的情况下寻找他们等将为我打破。大家都太熟悉AmbiguousMatchException .. – Mania 2011-05-09 18:53:05

+0

你应该澄清这个问题...我只是让你的测试通过失败 – 2011-05-09 18:56:44

+0

@mania - 看到更新只改变了断言条件 – 2011-05-09 19:02:12

相关问题