From: Marek Safar Date: Fri, 17 Jun 2016 16:44:45 +0000 (+0200) Subject: [reflection] Properties always use name and signature hidding rules. Fixes #41874 X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=1a820fcdc09b8f72d12a0973e25db7acc434d0cc;p=mono.git [reflection] Properties always use name and signature hidding rules. Fixes #41874 --- diff --git a/mcs/class/corlib/Test/System/TypeTest.cs b/mcs/class/corlib/Test/System/TypeTest.cs index cbf44c17f35..e1b49e6c868 100644 --- a/mcs/class/corlib/Test/System/TypeTest.cs +++ b/mcs/class/corlib/Test/System/TypeTest.cs @@ -456,6 +456,51 @@ namespace MonoTests.System } + class GetProperties_Overrides_Input + { + public class TestClass : BaseClass + { + public override object TestProperty { get; set; } + } + + public abstract class BaseClass + { + public virtual T TestProperty { get; set; } + } + + public class TestClass_Indexer : BaseClass_Indexer + { + public override object this[int arg] { set { } } + } + + public abstract class BaseClass_Indexer + { + public virtual T this[int arg] { set { } } + } + + public interface IB : IA + { + new object TestProperty { get; set; } + } + + public interface IA + { + 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 () { diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index d1a6856c9b4..b769d117545 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -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;