none
Nested Class Inheritence... RRS feed

  • Question

  • Well,

    I'm not sure if this is a problem of generics, but I'm noticing an annoying behavior of an inability to inherit from protected nested classes.

     

    Public Class MyClass
     protected overridable sub MyMethod()
     end sub
    end class
    
    Public Class MyDescendent
     inherits MyClass
     protected overrides sub MyMethod()
      mybase.mymethod()
     end sub
    end class

    Above, the protected moniker indicates a "class" only method, basically a method that is only accessible internally from the class it was defined in, and all descendants.

    Public Class MyClass
    
      Protected Class MyNested
      end class
    end class
    
    Public Class MyDescendent
     Inherits MyClass
     Protected Class MyNestedDescendent
      inherits MyClass.MyNested
     end class
    end class

    THe above here, depicts a similar theory, but i'm not sure i've this is 100% accurate.  The Protected Moniker again should refer to any element of the class that is reference-able only from the class it was declared in and subsequent descendant classes, which means i should be able to inherits fro MyNested in any descendant class of MyClass.

    I am currently working with a generic like this:

     

    Public Class MyClass(of T)
    
      Protected Class MyNested
       private _item as T
      End Class
    End Class
    
    Public Class MyDescendant(of A, B)
      inherits MyClass(of B)
    
      Protected Class MyDescendantNested
       inherits MyClass(of B).MyNested
       
       private _item2 as A
      End Class
    End Class


    The above, however, seems to be having a problem, as it claims that MyDescendent cannot access MyNested as MyNested is Protected.  This does not make any sense.  If I can view and read objects of type MyNested while in methods defined in MyDescendant, then why can I not create a descendant class of the MyNested within MyDescendant?  I understand that with the protected moniker, I cannot expose the MyNested, but that is the whole point.  I'm doing some background magic, and do not want the MyNested visible beyond the Class and its descendants.  The further annoyance is that when I mark MyNested as Public, i don't get any errors.

    Ideas? Explanation perhaps?

    Thanks

    Jaeden "Sifo Dyas" al'Raec Ruiner


    "Never Trust a computer. Your brain is smarter than any micro-chip."
    PS - Don't mark answers on other people's questions. There are such things as Vacations and Holidays which may reduce timely activity, and until the person asking the question can test your answer, it is not correct just because you think it is. Marking it correct for them often stops other people from even reading the question and possibly providing the real "correct" answer.
    Wednesday, April 28, 2010 6:19 PM

Answers

  • Vidya,

    I'm pretty sure we've already determined that Generics aren't the issue.  So why repost your same message that provides a link dealing only with generics.  The issue is nested classes .

    Now, for the time being I've resolved the issue by making my nested classes public, because I can't be dealing with these errors at the current moment.  The above example you've provided only shows the use of a generic collection, and has absolutely no bearing upon Nested Classes, and their protection level. 

    I did read somewhere, that the use of the Protected modifier is often assumed to operate in the manner I've tried to use it, given that protected members are visible to descendants, but that using the Modifier on a Nested Class is not directly the same as using it on a method.  And that Protected Nested Classes are not bound to the parent class instance as they are actually their own unique type, and are staticly bound, much the same as a Static Method (Shared in VB).  This means that the Nested Class is treated the same as a Protected Shared Method, and even though it is accessible from descendants of the same type, using the MyObject.MyNested notation actually is attempting to access the static protected element from the public class type moniker. 

    Basically, one could inherit from the protected nested class, but in effect it defeats the inheritance, as the "class" being inherited no longer belongs to the parent, but to the child.

    Public Class MyClass1
      Protected Shared Sub DoSomething()
      End Sub
    
      Protected Class MyNested
      End Class
    End Class
    
    Public Class MyClass2
     inherits MyClass1
    
     Protected Class MyNested2
       inherits MyClass1.MyNested '<- Wrong. This Is like Accessing
           'MyClass1.DoSomething(), the Protected Static binding 
           'makes mynested inaccessible to the public and "MyClass1" is public
     End Class
    
     Protected Class MyNested3
       inherits MyNested '<- this works, the same as calling DoSomething()
           'from within MyClass2 methods. However, this is in effect
           'declaring MyNested3 to be a descendant of 
           'MyClass2.MyNested, not MyClass1.MyNested
     End Class
    End Class
     

    I'm not exactly 100% on the interpretations of the compiler and how it arrives to these determinations.  Nor am I'm versed in why the C# compiler only results in a warning as opposed to the Error in VB.  Either way, the effect is the same, and regardless of generics the Nested Class inheritance issue revolves around the Static Binding of Nested Types. 

    Frankly, I disagree with this pattern, but I didn't invent the language, so we make due.  :)

    From my research I hope this explanation helps others in the future.

    Jaeden "Sifo Dyas" al'Raec Ruiner


    "Never Trust a computer. Your brain is smarter than any micro-chip."
    PS - Don't mark answers on other people's questions. There are such things as Vacations and Holidays which may reduce timely activity, and until the person asking the question can test your answer, it is not correct just because you think it is. Marking it correct for them often stops other people from even reading the question and possibly providing the real "correct" answer.
    • Marked as answer by JaedenRuiner Tuesday, May 4, 2010 2:25 PM
    Tuesday, May 4, 2010 2:23 PM

All replies

  • Hi Jaeden,

    This is not an issue of Generic for sure.

    Refer to this MSDN url http://msdn.microsoft.com/en-us/library/ms132397.aspx

    Scroll down to Example 2: and Change the code language to VB.

    Hope this helps. 

     

     


    Vidya Vrat Agarwal. MCPD,MCTS, MCT, MCSD .NET, MCAD .NET, MCSD. http://dotnetpassion.blogspot,com
    Wednesday, April 28, 2010 7:37 PM
  • Well, that had no bearing on the issue.  I know how to use generics quite well.  The question is about nested class inheritance. I was trying to understand why:

    Public Class MyClass
    
     Protected Class MyNested
     End Class
    End Class
    
    Public Class MyClass2
     inherits MyClass
    
      Protected Class MyNested
       Inherits MyClass.MyNested
      end class
    end class

    Creates an error that claims "MyNested" is not accessible due to protected. 

    Where:

    Public Class MyClass2
     inherits MyClass
    
     Protected MyNested2
      inherits MyNested
     End CLass
    End Class
    

    Doesn't have any issues.

    Similarly, If I changed the Protected to Public in the MyClass.MyNested defninition from example 1, then the MyClass2 definition from example 1 does not have any issue.  It's the use of the "inherits MyClass.MyNested", or if I had a method that had a MyNested Parameter, in the MyCLass2 Definition overriding that method, the parameter would initially be listed as X as MyClass.MyNested as it is inherited from the parent.  In the protected version this has a problem and I have to eliminate the MyClass. part of the parameter declaration.  When It's public I don't.  Why?

    Thanks

    Jaeden "Sifo Dyas" al'Raec Ruiner


    "Never Trust a computer. Your brain is smarter than any micro-chip."
    PS - Don't mark answers on other people's questions. There are such things as Vacations and Holidays which may reduce timely activity, and until the person asking the question can test your answer, it is not correct just because you think it is. Marking it correct for them often stops other people from even reading the question and possibly providing the real "correct" answer.
    Thursday, April 29, 2010 3:00 PM
  • In C#, the first example would give a warning that MyClass2.MyNested is hiding MyClass.MyNested, but no error. Didn't know that VB has different rules for access modifiers.

    Cristian.

    Thursday, April 29, 2010 4:00 PM
  • Hi Jaeden,

    This is not an issue of Generic for sure.

    Refer to this MSDN url http://msdn.microsoft.com/en-us/library/ms132397.aspx

    Scroll down to Example 2: and Change the code language to VB.

    Hope this helps. 

     


    Vidya Vrat Agarwal. MCPD,MCTS, MCT, MCSD .NET, MCAD .NET, MCSD. http://dotnetpassion.blogspot,com
    Tuesday, May 4, 2010 4:13 AM
  • Vidya,

    I'm pretty sure we've already determined that Generics aren't the issue.  So why repost your same message that provides a link dealing only with generics.  The issue is nested classes .

    Now, for the time being I've resolved the issue by making my nested classes public, because I can't be dealing with these errors at the current moment.  The above example you've provided only shows the use of a generic collection, and has absolutely no bearing upon Nested Classes, and their protection level. 

    I did read somewhere, that the use of the Protected modifier is often assumed to operate in the manner I've tried to use it, given that protected members are visible to descendants, but that using the Modifier on a Nested Class is not directly the same as using it on a method.  And that Protected Nested Classes are not bound to the parent class instance as they are actually their own unique type, and are staticly bound, much the same as a Static Method (Shared in VB).  This means that the Nested Class is treated the same as a Protected Shared Method, and even though it is accessible from descendants of the same type, using the MyObject.MyNested notation actually is attempting to access the static protected element from the public class type moniker. 

    Basically, one could inherit from the protected nested class, but in effect it defeats the inheritance, as the "class" being inherited no longer belongs to the parent, but to the child.

    Public Class MyClass1
      Protected Shared Sub DoSomething()
      End Sub
    
      Protected Class MyNested
      End Class
    End Class
    
    Public Class MyClass2
     inherits MyClass1
    
     Protected Class MyNested2
       inherits MyClass1.MyNested '<- Wrong. This Is like Accessing
           'MyClass1.DoSomething(), the Protected Static binding 
           'makes mynested inaccessible to the public and "MyClass1" is public
     End Class
    
     Protected Class MyNested3
       inherits MyNested '<- this works, the same as calling DoSomething()
           'from within MyClass2 methods. However, this is in effect
           'declaring MyNested3 to be a descendant of 
           'MyClass2.MyNested, not MyClass1.MyNested
     End Class
    End Class
     

    I'm not exactly 100% on the interpretations of the compiler and how it arrives to these determinations.  Nor am I'm versed in why the C# compiler only results in a warning as opposed to the Error in VB.  Either way, the effect is the same, and regardless of generics the Nested Class inheritance issue revolves around the Static Binding of Nested Types. 

    Frankly, I disagree with this pattern, but I didn't invent the language, so we make due.  :)

    From my research I hope this explanation helps others in the future.

    Jaeden "Sifo Dyas" al'Raec Ruiner


    "Never Trust a computer. Your brain is smarter than any micro-chip."
    PS - Don't mark answers on other people's questions. There are such things as Vacations and Holidays which may reduce timely activity, and until the person asking the question can test your answer, it is not correct just because you think it is. Marking it correct for them often stops other people from even reading the question and possibly providing the real "correct" answer.
    • Marked as answer by JaedenRuiner Tuesday, May 4, 2010 2:25 PM
    Tuesday, May 4, 2010 2:23 PM