Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>We'll have to deal in terms of the methods of the property here rather than the property itself, because it is the get/set methods of the property that actually get overridden rather than the property itself. I'll use the get method as you should never have a property without one, though a complete solution should check for the lack of one.</p> <p>Looking at the IL emitted in a number of cases, the 'get' method of the base property will have the metadata tokens (this is from the C# compiler; others may not emit the <code>hidebysig</code> depending on their method hiding semantics, in which case the method would be hide-by-name):</p> <pre><code>non-virtual : .method public hidebysig specialname instance virtual : .method public hidebysig specialname newslot virtual instance </code></pre> <p>The derived one will have the following tokens:</p> <pre><code>override : .method public hidebysig specialname virtual instance new : .method public hidebysig specialname instance new virtual : .method public hidebysig specialname newslot virtual instance </code></pre> <p>So we can see from this that it isn't possible to tell purely from the method's metadata tokens whether it is <code>new</code> because the non-virtual base method has the same tokens as the non-virtual <code>new</code> method, and the virtual base method has the same tokens as the <code>new virtual</code> method.</p> <p>What we <em>can</em> say is that if the method has the <code>virtual</code> token but not the <code>newslot</code> token then it overrides a base method rather than shadows it, i.e.</p> <pre><code>var prop = typeof(ChildClass).GetProperty("TempProperty"); var getMethod = prop.GetGetMethod(); if ((getMethod.Attributes &amp; MethodAttributes.Virtual) != 0 &amp;&amp; (getMethod.Attributes &amp; MethodAttributes.NewSlot) == 0) { // the property's 'get' method is an override } </code></pre> <p>Assuming, then, that we find the 'get' method is not an override, we want to know whether there is a property in the base class that it is shadowing. The problem is that because the method is in a different method table slot, it doesn't actually have any direct relationship to the method it is shadowing. So what we're actually saying is "does the base type have any method which meets the criteria for shadowing", which varies depending on whether the method is <code>hidebysig</code> or hide-by-name. </p> <p>For the former we need to check whether the base class has any method which matches the signature exactly, whereas for the latter we need to check whether it has any method with the same name, so continuing the code from above:</p> <pre><code>else { if (getMethod.IsHideBySig) { var flags = getMethod.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic; flags |= getMethod.IsStatic ? BindingFlags.Static : BindingFlags.Instance; var paramTypes = getMethod.GetParameters().Select(p =&gt; p.ParameterType).ToArray(); if (getMethod.DeclaringType.BaseType.GetMethod(getMethod.Name, flags, null, paramTypes, null) != null) { // the property's 'get' method shadows by signature } } else { var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; if (getMethod.DeclaringType.BaseType.GetMethods(flags).Any(m =&gt; m.Name == getMethod.Name)) { // the property's 'get' method shadows by name } } } </code></pre> <p>I think this is most of the way there, but I still don't think it's exactly right. For a start I'm not totally familiar with hiding by name as C# doesn't support it and that's pretty much all I use, so I may be wrong in the code here that indicates an instance method could shadow a static one. I also don't know about the case sensitivity issue (e.g. in VB could a method called <code>Foo</code> shadow a method called <code>foo</code> if they both had the same signature and were both <code>hidebysig</code> - in C# the answer is no but if the answer is yes in VB then it means the answer to this question is actually nondeterministic).</p> <p>Well, I'm not sure how much help all this is, other than to illustrate that it's actually a much harder problem than I thought it would be (or I've missed something really obvious in which case I'd like to know!). But hopefully it's got sufficient content that it helps you achieve what you're trying to do.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload