0

According to this StackOverflow question, one can use the Type.IsAbstract and Type.IsSealed properties to determine if a class is static. However, look at the following test:

[Fact]
public void ActivatorNotAbstract()
{
    var activatorType = typeof(Activator);

    Assert.True(activatorType.IsClass);
    Assert.True(activatorType.IsSealed);
    Assert.True(activatorType.IsAbstract);
}

This test fails because the last assertion is not true, although System.Activator is defined as a static class. This is both true for .NET Core 2.0 (and probably previous versions) as well as .NET 4.5 (and probably other versions, too). You can also find the above test in this GitHub repo.

Why is Activator special in this regard? I couldn't find any other static class in the BCL that would behave this way.

Edit after answer from Camilo

You are right, I didn't look thoroughly - in .NET, the class is actually sealed:

Activator is Sealed in .NET

However, from .NET Core Metadata, it appears to be static:

.NET Core Activator is Static

Now, the actual question should be: why appears Activator as a static class in .NET Core (and in NetStandard, too, btw.), but actually is a sealed class?

feO2x
  • 5,358
  • 2
  • 37
  • 46

3 Answers3

4

The issue here is you assumed the following:

although System.Activator is defined as a static class

Interestingly, this is technically correct since the library you compile against defines System.Activator as a static class. This can for example be seen at the source code of the System.Runtime reference assembly or the in a part of the netstandard.dll reference assembly source code.

However, these libraries are meant as a compile-time interface and the actual runtime implementation may derivate a little from this declaration.

In fact, both .NET Core and .NET Framework implement the class as public sealed class Activator (.NET Core) or public sealed class Activator : _Activator (.NET Framework).

This implementation causes IsAbstract to return false.

Martin Ullrich
  • 94,744
  • 25
  • 252
  • 217
  • Thanks for your explanation, I wasn't aware that a compile target and implementation class can differ in that way. – feO2x Aug 15 '17 at 20:21
  • 2
    Yes there are a few places but the difference only shows when reflecting into the types. The effect of the contract is the same - you can't inherit from `Activator` nor instantiate it (private constructor in implementation). – Martin Ullrich Aug 15 '17 at 20:25
3

If you are referring to the System.Activator class, it is not static at all, look at the .NET source code

public sealed class Activator : _Activator

Hence:

  • It's a class
  • It's sealed
  • It's not abstract
Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
  • Note that a very important part of the question is in the linked question: https://stackoverflow.com/questions/1175888/determine-if-a-type-is-static , which states that type.IsAbstract && type.IsSealed means it is a static class – binary01 Aug 15 '17 at 20:10
  • Thanks for your answer, I've updated my question. Activator is actually a sealed class in .NET, but from .NET Core metadata, it appears to be static. – feO2x Aug 15 '17 at 20:16
  • 1
    Actually, you can create an instance of `Activator` with (... tada!) `Activator a = Activator.CreateInstance(typeof(Activator), BindingFlags.NonPublic | BindingFlags.Instance, null, null, null);`. You could never do that with an abstract type. – Jeppe Stig Nielsen Aug 15 '17 at 20:17
-3

If a class is sealed it means that it cannot be inherited by a child class. If a class is abstract it means that the class can only be used by calling a child class of it. Essentially abstract and sealed are mutually exclusive.

See: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed

0liveradam8
  • 752
  • 4
  • 18
  • I know what abstract and sealed means, see updated question. – feO2x Aug 15 '17 at 20:17
  • Actually `static` is a combination of both. At IL-level (what C# compiles into), the class is marked as `abstract` and `sealed`. C# has its own modifier keyword for this combination (`static`) and you can't combine the `abstract` and `sealed` modifiers. See the question linked by the OP. – Martin Ullrich Aug 15 '17 at 20:31