diff options
author | Marek Safar <marek.safar@gmail.com> | 2016-06-20 15:21:33 +0300 |
---|---|---|
committer | Marek Safar <marek.safar@gmail.com> | 2016-06-20 20:36:41 +0300 |
commit | 9bdc135cdf856ac9171a8a7e441a0775b1df51e3 (patch) | |
tree | afe4c256b6f3976a3d2cf06fc77a19705b80a4af | |
parent | 587a89e17c038521eaf52866d25affadc52db4ff (diff) |
[reflection] Properties always use name and signature hidding rules. Fixes #41874
-rw-r--r-- | mcs/class/corlib/Test/System/TypeTest.cs | 59 | ||||
-rw-r--r-- | mono/metadata/icall.c | 19 |
2 files changed, 71 insertions, 7 deletions
diff --git a/mcs/class/corlib/Test/System/TypeTest.cs b/mcs/class/corlib/Test/System/TypeTest.cs index 541acb6afb7..3f2d6283fb7 100644 --- a/mcs/class/corlib/Test/System/TypeTest.cs +++ b/mcs/class/corlib/Test/System/TypeTest.cs @@ -456,6 +456,65 @@ 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; } + } + + public class TestClass_HiddenProperty : BaseClass_HiddenProperty + { + public new virtual string Prop { set { } } + } + + public class BaseClass_HiddenProperty + { + public virtual string Prop { 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); + + var prop_2 = typeof (GetProperties_Overrides_Input.TestClass_HiddenProperty).GetProperty ("Prop"); + Assert.AreEqual (typeof (GetProperties_Overrides_Input.TestClass_HiddenProperty), prop_2.DeclaringType); + + Assert.AreEqual (1, typeof (GetProperties_Overrides_Input.TestClass).GetProperties().Length); + Assert.AreEqual (1, typeof (GetProperties_Overrides_Input.TestClass_Indexer).GetProperties().Length); + Assert.AreEqual (1, typeof (GetProperties_Overrides_Input.TestClass_HiddenProperty).GetProperties().Length); + } + [Test] // GetProperties (BindingFlags) public void GetProperties_Flags () { diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 6f8827dfb84..3a7706caa6d 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -3623,12 +3623,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 && method1->slot == method2->slot) + return TRUE; + + 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)); } @@ -3654,10 +3659,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; |