When I worked on the semantic parser of the LINQ over C# project I reached the point to check if in a class declaration has a non-static base class (the C# language specification does not allow it). It must be easy with the Type class using reflection methods:
public void IsStatic(Type type)
{
return type.IsStatic;
}
This looks nice, however, it does not work L. The Type class does not have an IsStatic property. “Don’t worry, there must be a method or another property for this check” said I to myself, but after searching in the MSDN documentation it come to light for me there is no such member of Type. Does it mean there is no way to ask if a type is static or not?
Murphy’s Law says: “If all your trials fail, read the user manual”. For a .NET developer it means “use Reflector”! So, I examined a few static class with Reflector.
The System.Environment type is a static class; the C# disassembler of Reflector also indicated this fact. The declaration of this type in IL looks like this:
.class public abstract auto ansi sealed beforefieldinit Environment
extends System.Object
{
}
Could it be that Environment is abstract and sealed at the same time? It cannot be! If it is abstract it cannot be directly instantiated, only one of its derived classes allows instantiation. If it is sealed it cannot be used as a base class. Being abstract and sealed at the same time sounds “interesting”.
But, please observe, it corresponds with the semantics of a static class: it cannot be instantiated and cannot be a base class! You cannot declare a C# class like this:
public abstract sealed class MyClass { ... }
You’ll be given a CS0418 error (An abstract class cannot be sealed or static) by the C# compiler. Writing the definition above is not allowed in C# but is legal in IL and so the C# compiler can emit code accepted by the CLR. In this IL code a type can be abstract and sealed at the same time. Searching in blogs I could find the information that .NET CLR does not know the idea of static classes, however allows using the abstract and sealed type flags simultaneously. These flags are also used by the CLR to optimize its behavior, for example the sealed flag is used call virtual methods of sealed class like non-virtuals.
So, to ask if a type is static or not, you can use this method:
public void IsStatic(Type type)
{
return type.IsAbstract && type.IsSealed;
}
You can also create an extension method for Type to emulate it has an IsStatic method.
Posted
Aug 04 2008, 09:00 AM
by
inovak