Excluded overriden members, appear as inherited.

Nov 12, 2007 at 10:24 AM
Hallo,

I have the following case:

Configuration:
DocumentInheritedMembers = True
DocumentPrivates = False

A base class declares an overridable member. I override it in a derived class and I add the <exclude/> tag. (I also add EditorBrowsableAttribute(EditorBrowsableState.Never) and BrowsableAttribute(False) for programmatical reasons). The member is also automatically unchecked in the API Filter window since it has an <exclude/> tag applied. However, the base class member (inherited) appears in the final documentation for the derived class. Same thing happens if a derived class shadows a member of the base class and then excludes it, or changes its access level to private.

I tried the following 4 tests:

1. Using only <exclude/> (no attributes)
2. Using only the attributes (no exclude)
3. Using only the attributes, then unchecked the member in the API Filter window.
4. Using no attributes and no <exclude/>, then unchecked the member in the API Filter window.

Using only the attributes (2), resulted in the member normally appearing in the derived class documentation. (Obviously Sandcastle and SHFB do not take these attributes into consideration.) In the rest 3 cases, the same issue appeared: The base class member appears in the derived class documentation.

How can I exclude a certain inherited member from a derived class, while letting the rest of inherited members appear? (It's useless to mention that I cannot afford excluding the member in the base class itself. The member should appear in derived classes that do not override it.)

Thank You.
Coordinator
Nov 12, 2007 at 5:00 PM
Edited Nov 12, 2007 at 5:08 PM
If you exclude a member using <exclude/> or the API filter, it will be removed from all derived classes as well. However, if the method is virtual and is overridden in a derived class, then the method will appear in the derived class. If you don't want to see the derived version, you need to apply the <exclude/> tag to it as well or remove it via the API filter too. Using either method, you cannot remove it from the base class but have the base class method appear in the derived classes. I guess what you need to do is only use <exclude/> or the API filter on the derived class in which you do not want the method seen. That way, it will appear in the base class and all others derived from it.

Eric
Nov 13, 2007 at 5:39 AM
Hallo,

Actually, what I describe in detail above, is exactly the opposite. I do not want to exclude the virtual member from the base class (and therefore from all its derived classes). I want to exclude an overriden version of the member, from the documentation of a derived class.
What you suggest:

...only use <exclude/> or the API filter on the derived class in which you do not want the method seen. That way, it will appear in the base class and all others derived from it.

is something I tried already as I mention in the 4 tests above. What happens is that the documentation of the inherited member appears in the documentation of the derived class, in the place of the excluded override, as if the member had never been overriden.

Example:


Imports System.ComponentModel
 
Public Class Customer
 
    Private _ID As Int32
    Private _Name As String
 
    ''' <summary>
    ''' Gets the unique ID of this Customer.
    ''' </summary>
    ''' <returns>A <see cref="Int32"/> value representing the customer's unique ID.</returns>
    Public Overridable ReadOnly Property ID() As Int32
        Get
            Return _ID
        End Get
    End Property
 
    ''' <summary>
    ''' Gets the full name of the Customer.
    ''' </summary>
    ''' <returns>A <see cref="String"/> value representing the customer's name.</returns>
    Public Overridable ReadOnly Property Name() As String
        Get
            Return _Name
        End Get
    End Property
End Class
 
Public Class Visitor
    Inherits Customer
 
    ''' <summary>
    ''' This type of customer cannot have a unique ID.
    ''' </summary>
    ''' <remarks>This property must not appear in the documentation of this class.</remarks>
    ''' <exclude/>
    <EditorBrowsable(EditorBrowsableState.Never)> _
    <Browsable(False)> _
    Public Overrides ReadOnly Property ID() As Integer
        Get
            Return 0
        End Get
    End Property
End Class

Documentation produced for the derived (Visitor) class:

(Members Page)

Name Description
ID Gets the unique ID of this Customer. (Inherited from Customer)
Name Gets the full name of the Customer. (Inherited from Customer)

Notice how the base class (inherited) property ID appears in the documentation of the derived class Visitor, in place of the excluded override, as if it is not overriden at all. This completely misleads the user who thinks he can actually get an ID, since that's what the documentation of the virtual method in the base class says. Things get even more complicated when the attributes successfully hide the property in completors and Object Browsers, but the member appears in the documentation of the derived class.
Since I override and exclude the ID property, it should not appear at all in the documentation of the derived class Visitor (nor in the TOC under Visitor-Properties).
Coordinator
Nov 13, 2007 at 4:03 PM
I don't think that what you are trying to do is possible. All the attributes and <exclude/> tag do is hide the member in the documentation and object browser. The reality is that the property is still there and can be used even if you can't "see" it. If you were to derive a class from Visitor, you could override ID and make it return a value. You could also apply attributes to make it visible everywhere too. I think the only viable option is to leave the property in there and note that it cannot be used. You can enforce this by throwing an NotImplementedException rather than returning zero.

Eric
Jul 16, 2010 at 7:15 PM

I know this post is from over two years ago, but in case someone finds this doing a search, as I did:

I have this exact situation; that is, I want to omit properties from my documentation which are marked with the Browsable attribute = false.

 

Here is what I did, and it seems to work. (Disclaimer: I have done minimal testing of this solution).

I have Sandcastle Help File Builder version 1.9.1.0 (July 2010) and Sandcastle 2.6.1062.1 (June 2010).

My Sandcastle Help File Builder config:

Under Visibility, DocumentAttributes is True

Under Build, PluginConfigurations, I added the XPath Reflection File Filter.  My configuration for the plugin has the following entries:

/reflection/apis/api/attributes/attribute[type/@api="T:System.ComponentModel.BrowsableAttribute"]/argument[value="False"]/../../..

/reflection/apis/api/elements/element/attributes/attribute[type/@api="T:System.ComponentModel.BrowsableAttribute"]/argument[value="False"]/../../..

/reflection/apis/api/elements/element/attributes

/reflection/apis/api/attributes

 

The first two remove entries where the Browsable attribute is false.  The last two are included to remove all attributes if you don't want to include attributes in your documentation.

One last important note.  Do not specify the <exclude/> tag on a property if it has Browsable(false) attribute.  If you do this, the property is removed before the XPath Reflection File Filter processing occurs.  This results in the behavior where an overridden property will appear in the doc with a reference to the base class.