[reflection] Properties always use name and signature hidding rules. Fixes #41874
authorMarek Safar <marek.safar@gmail.com>
Fri, 17 Jun 2016 16:44:45 +0000 (18:44 +0200)
committerMarek Safar <marek.safar@gmail.com>
Fri, 17 Jun 2016 16:44:45 +0000 (18:44 +0200)
mcs/class/corlib/Test/System/TypeTest.cs
mono/metadata/icall.c

index cbf44c17f358df1b94a0c1977772271af40ac3e4..e1b49e6c8688b8c02104e2d85ba9d87052e60b35 100644 (file)
@@ -456,6 +456,51 @@ namespace MonoTests.System
 
                }
 
+               class GetProperties_Overrides_Input
+               {
+                       public class TestClass : BaseClass<object>
+                       {
+                               public override object TestProperty { get; set; }
+                       }
+
+                       public abstract class BaseClass<T>
+                       {
+                               public virtual T TestProperty { get; set; }
+                       }
+
+                       public class TestClass_Indexer : BaseClass_Indexer<object>
+                       {
+                               public override object this[int arg] { set { } }
+                       }
+
+                       public abstract class BaseClass_Indexer<T>
+                       {
+                               public virtual T this[int arg] { set { } }
+                       }
+
+                       public interface IB : IA<object>
+                       {
+                               new object TestProperty { get; set; }
+                       }
+
+                       public interface IA<T>
+                       {
+                               T TestProperty { get; set; }
+                       }
+               }
+
+               [Test]
+               public void GetProperties_Overrides ()
+               {
+                       Assert.AreEqual (1, typeof (GetProperties_Overrides_Input.IB).GetProperties().Length);
+
+                       var prop = typeof (GetProperties_Overrides_Input.TestClass).GetProperty ("TestProperty");
+                       Assert.AreEqual (typeof (GetProperties_Overrides_Input.TestClass), prop.DeclaringType);
+
+                       Assert.AreEqual (1, typeof (GetProperties_Overrides_Input.TestClass).GetProperties().Length);
+                       Assert.AreEqual (1, typeof (GetProperties_Overrides_Input.TestClass_Indexer).GetProperties().Length);
+           }
+
                [Test] // GetProperties (BindingFlags)
                public void GetProperties_Flags ()
                {
index d1a6856c9b44e7824e284b4eda349b274817f442..b769d1175451d81818677752adbdde6fa2a1d02c 100644 (file)
@@ -4157,12 +4157,17 @@ property_hash (gconstpointer data)
 }
 
 static gboolean
-method_declaring_signatures_equal (MonoMethod *method1, MonoMethod *method2)
+property_accessor_override (MonoMethod *method1, MonoMethod *method2)
 {
-       if (method1->is_inflated)
-               method1 = ((MonoMethodInflated*) method1)->declaring;
-       if (method2->is_inflated)
-               method2 = ((MonoMethodInflated*) method2)->declaring;
+       if (method1->slot != -1 && method2->slot != -1)
+               return method1->slot == method2->slot;
+
+       if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
+               if (method1->is_inflated)
+                       method1 = ((MonoMethodInflated*) method1)->declaring;
+               if (method2->is_inflated)
+                       method2 = ((MonoMethodInflated*) method2)->declaring;
+       }
 
        return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
 }
@@ -4188,10 +4193,10 @@ property_equal (MonoProperty *prop1, MonoProperty *prop2)
           the indexer came from method 1 or from method 2, and we
           shouldn't conflate them.   (Bugzilla 36283)
        */
-       if (prop1->get && prop2->get && !method_declaring_signatures_equal (prop1->get, prop2->get))
+       if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
                return FALSE;
 
-       if (prop1->set && prop2->set && !method_declaring_signatures_equal (prop1->set, prop2->set))
+       if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
                return FALSE;
 
        return TRUE;