views:

72

answers:

2

Assume the following: we have class B, which is a private class nested inside class A. There isn't any class inheriting from class B. The question is: will the compiler automatically mark class B as Sealed? (NonInheritable in VB). Is there any good reason for the compiler not to mark class B as sealed?

My line of thought is this: since class B is nested inside class A and is private, and there is no other class inheriting from class B, it should be safe to seal it, because it can't be inherited outside class A (not even by subclasses of A).

Class A
    Private Class B  
    End Class
End Class
+1  A: 

I didn't check, but I suppose that it will not do that. In any way, the JIT can determine whether a class can have descendants or not, so that I don't expect any difference at runtime.

Lucero
The JIT can determine if a class has descendents but I don't believe that it does outside the presence of the sealed bit on a type. I don't have any references to back me up on this but I'm fairly certain on this point.
JaredPar
@JaredPar, as far as I know many Java VMs have been doing this for a long time (which is really necessary due to the default-virtual-method - http://www.ibm.com/developerworks/library/j-jtp12214/ ), and I'm pretty sure that MS does do such optimizations if they have been seen as helping performance.
Lucero
@Lucero the JIT definitely does for explititly sealed classes. But there is only a very small subset of cases where it can do so for non-sealed classes. I'm not sure if that micro-optimization would be worth it. But like I said, I can't find any docs one way or the other.
JaredPar
@JaredPar, why do you think that this subset is so small? The CLR does know at any time whether a type has descendants in or not. If an assembly is loaded later on, it could throw away or fix the already compiled methods which involve those calls. Also, there are cases such as the one here where it is clear that there will be no inheritance. Again as far as In know, in Java they go as far as inlining virtual methods when those are seen as implicitly "final" and qualify for inlining like the same nonvirtual method would.
Lucero
@Lucero, the CLR only knows the type currently doesn't have any descendants. At any point in time a new assembly could enter the `AppDomain` which is a descendant of the class. Only if the type is sealed or falls into another very small use case can the CLR know the type has no descendents.
JaredPar
If it's a private nested class, then it cannot have any descendants in other assemblies - visibility requirements apply to correct IL, even if it's otherwise unverifiable. So, in practice, the JIT can make a valid assumption that a private nested class that doesn't have any classes derived from it in the same assembly is effectively sealed.
Pavel Minaev
+6  A: 

The compiler will not automatically mark this type as sealed.

True in this very specific scenario there is no real value in leaving the class as unsealed. However determining that you are in this scenario is not always so easy. You have to consider the following

  • The type is private
  • Must consider the presence of partial classes
  • Other private nested types could inherit.

These are not impossible to calculate but it's not trivial either. It's much cheaper to ask the user to just seal the type themselves

JaredPar