Is marking a class as static a binary breaking change? - c#

I have a utility class that only contains static methods. If I mark the class as static, is that a breaking binary change?
I've compared the IL for both, and besides the loss of the default constructor (that should never be used), I can see the following differences...
Class not marked as static:
.class public auto ansi beforefieldinit MyNamespace.MyClass
Class marked as static:
.class public auto ansi abstract sealed beforefieldinit MyNamespace.MyClass
I can't see why that would be a breaking change, but...?

It depends on the usage of your class by other code: potential usage of static classes is a lot more restricted than that of non-static ones.
If the class has been used like static even though it hasn't been static at the time, the code is not going to break.
If the class has been used like non-static one, i.e. has been inherited or instantiated, then the change is breaking.
Since in general you cannot guarantee that your non-static class is used in a certain way, making a formerly non-static class a static one should be considered a breaking change. If you have code outside your control that depends on your class, designate the old class obsolete, and make a new static class to be used instead of it.

As you can see there are two modifiers added for static:
abstract: means you can't instantiate it
sealed: means you can't inherit from it
So in your code if you are instantiating this class or you have a type that inherits from it, your code will be broken.

Yes that is a breaking change. If the consumer of your library has subclassed your class, it will be broken.
Given that the class only contains bunch of static methods there is no point in inheriting it, but if someone did, that will stop their code from compiling.
Also note that you can't even declare a field of a type which is a static class. If the consumer had a field, property or something of your type, that will also break.
So the answer depends upon how the consumer library used it.

Related

Abstract class cannot be sealed in c#?

I read somewhere
"Abstract and Sealed modifiers are equivalent to a class which is static"
I also found that
"When you declare a static class, internally the compiler marks the class abstract and sealed, and creates a private constructor in the IL code"
so, I decided to do this:
static class A
{
public static void test()
{
Console.WriteLine("test");
}
}
Now, the class "A" cannot be inherited nor instantiated.
So, let us write a class B using abstract to prevent instantiation and using sealed to prevent inheritance.
But, this approach fails.
which should be equivalent to
public abstract sealed class B
{
private B()
{
}
public void test()
{
Console.WriteLine("test");
}
}
But I recieve an error stating "error CS0418:B': an abstract class cannot be sealed or static"` . Any ideas why this is not possible ?
Thanks in advance for your answers.
Having checked the IL of the System.Directory class (which is static), it is declared in IL as:
.class public auto ansi abstract sealed beforefieldinit System.IO.Directory
extends System.Object
{
...
Further, this article (http://msdn.microsoft.com/en-us/library/ms229038.aspx) suggests that the CLR handles static classes as abstract sealed classes to support languages that do not support directly delcaring static classes (eg C++).
Thus in conclusion, static classes in C# are syntactic sugar for sealed abstract classes with private constructors. I for one am glad of that as "static" is a lot easier to write and a lot easier to get right.
By definition a sealed class enables you to prevent the inheritance of a class or certain class members that were previously marked virtual.
Abstract keyword enables you to create classes and class members that are incomplete and must be implemented in a derived class.
(Source: http://msdn.microsoft.com/en-us/library/ms173150.aspx)
This would imply that any class marked abstract would not be able to be sealed, since you wouldn't be able to derive it anywhere.
The code you mentioned doesn't make any sense.
All answers somehow take the technical point of view. Such as: the class can't be "must inherit" and "can't inherit" at the same time. But I think that is not the main reason, as clearly, the "static" is just that.
I think David Amo's answer has touched the real answer a bit, by stating: "it is a lot easier to get right".
I am convinced that Anders Hejlsberg's idea when designing C# was to eliminate ambiguity and thus decrease a chance for error. That's why "virtual" goes with "override" (override has to be explicit, not implicit as in Java). And in this case, "abstract"+"sealed" would be the same as "static". Two ways of defining the same principle. This is:
- more error prone (imagine you have abstract somewhere and put sealed there accidently without noticing, onw compiler prevents that)
- more difficult to work with (imagine you want to search for all static classes in your project)
So my point is, this entire design leads the developers the right way of doing things.

In C#, what is the purpose of marking a class static?

In C#, what is the purpose of marking a class static?
If I have a class that has only static methods, I can mark the class static or not. Why would I want to mark the class static? Would I ever NOT want to mark a class static, if all the methods are static, and if I plan to never add a non-static method?
I looked around and saw some similar questions, but none that were just like this.
Marking a class as static is a declarative statement that you only intend for this type to have static and const members. This is enforced by the compiler and prevents you from accidentally adding an instance method to the type.
Other advantages
Extension methods can only be defined in static classes
Prevents users from creating an instance of the class
Prevents use of the type as a generic argument (thanks Eric!)
Marking a class as static gets you two important things.
Compiler verification that you only put static members in a class.
An obvious statement to readers of your code that this class is only a container for static members.
The feature was invented in response to a bug in NDP v1.0, where a un-callable non-static member was included in the System.Environment class.
If you would like to write extension methods, you have to use a static class. Otherwise it is to show the class will never have any instance data.
It is a convention specific to the C# language, the CLR has no notion of static classes. It ensures that you cannot accidentally add an instance member in the class, cannot inherit the class and client code cannot accidentally create an instance of the class. The underlying TypeAttributes for the class are Abstract and Sealed. Abstract ensures that the new operator can't work, Sealed ensures that you can't inherit from the class.
Also by convention, extension methods must be static members of a static class. VB.NET does it differently, it requires the [Extension] attribute.
Using static classes in your code is not necessary, but it is useful. Their contract is very descriptive, it makes your code easier to understand. But be careful not to use them as a vehicle to write procedural code instead of OOP code.
You mark a class static if you want to force it to contain only static methods, a typical helper class. If you put an instance method the compiler will complain - this is good. In version 1 of the .NET framework there was a class, don't remember which one, that was meant to ship with only static methods. Accidentally one of those methods did not get the static modifier. Because this feature did not exist at the time the bug was spotted very late, after shipping. They did make the constructor private and as such the method could not be used.

internal abstract methods. Why would anyone have them?

I was doing some code review today and came across an old code written by some developer. It goes something like this
public abstract class BaseControl
{
internal abstract void DoSomething();
}
If you have a derived class within the same assembly, it would work
public class DerivedControl : BaseControl
{
internal override void DoSomething()
{
}
}
But deriving the base class in a different assembly would give compile time error
DerivedControl does not implement inherited abstract member 'BaseControl.DoSomething()
That got me thinking. Why would anyone declare a method as internal abstract ?
The original programmer wanted to make a derived control available to client code. But prevent the client from inheriting and messing with the virtual method. That's not a bad idea, it is usually easy to break a base class by overriding a method and doing something like forgetting to call the base class method.
One obvious case is where the method receives or returns an internal type. For example, the core methods of the WPF Transform classes process some internal interop types, which WPF doesn't expose as part of its public API. Because the signature includes internal types, the method can't be public or protected. And yet clearly it's appropriate (necessary!) for the various Transform classes to work polymorphically. Therefore the base methods in Transform/GeneralTransform have to be internal.
Another, but related reason is to prevent external derivation. After all, the WPF architects could have exposed a "safe" version of the internal interop types in a protected abstract method, so that users could create their own Transform classes. They didn't because they didn't want to have to cope with the ways that people might use that capability, e.g. creating non-affine transforms. Allowing external derivation would have made the job of other classes in WPF hugely more complex, so the architects decided to allow only "approved" derived classes by making an abstract method internal.
My initial reaction was that there is no good reason, if you want to prevent external inheritance then you should mark the class internal. But that means that the class is totally hidden to other assemblies.
I suppose this method prevents external inheritance while retaining visibility.
By defining a method as internal abstract you want to make sure that only the class in the same assembly can have its implementation for your method.
now if you distribute a dll of it this will avoid the client to inherit and mesup the implementation.

C# inheritence and static classes

Why can't a static class be inherited into a normal class?
If B inherits from (is a subclass of) A, that means an instance of B can be stored in a variable of type A, and its virtual methods will call those of class B.
For static classes, you don't have the concept of an instance of the class, so there's no way to inherit. You might have better luck with a static (singleton) reference to a regular class.
From Static Classes and Static Class Members (C# Programming Guide)
Creating a static class is therefore
basically the same as creating a class
that contains only static members and
a private constructor. A private
constructor prevents the class from
being instantiated. The advantage of
using a static class is that the
compiler can check to make sure that
no instance members are accidentally
added. The compiler will guarantee
that instances of this class cannot be
created.
Static classes are sealed and
therefore cannot be inherited. They
cannot inherit from any class except
Object. Static classes cannot contain
an instance constructor; however, they
can contain a static constructor.
As an alternative to inheriting from a static class, you can assign extension methods to interfaces.
You can not inherit a static class - The reason is simple. Static classes are marked as abstract and sealed in compiled IL which can be neither instantiated nor inherited.
This is actually by design. There seems to be no good reason to inherit a static class. It has public static members that you can always access via the class name itself. The only reasons I have seen for inheriting static stuff have been bad ones, such as saving a couple of characters of typing.
There may be reason to consider mechanisms to bring static members directly into scope (and we will in fact consider this after the Orcas product cycle), but static class inheritance is not the way to go: It is the wrong mechanism to use, and works only for static members that happen to reside in a static class.
(Mads Torgersen, C# Language PM)
Source:
Why can't I inherit static classes?

Why is the .NET Colors class not static?

I was browsing the colors class's source in reflector and it's just a sealed class. But all members are static. So why would anyone create a copy of the Colors class?
It lies inside:
System.Windows.Media.Colors
A static class is just a sealed abstract class with private constructor no constructors (as in, no constructors at any accessibility level, not even ones generated by the compiler) [fixed per Eric's comment]. The C# keyword static is simply a shorthand for that, and also forces you to make all members static, but for API clients it's exact same thing.
Given that work on WPF (then Avalon) began before .NET 2.0 was released, it could be that this particular class was written before static class appeared. Or perhaps the author was simply unaware of that language feature.
For me, Colors.AliceBlue and Colors.AntiqueWhite (the first and the second static property of Colors class :)) should be difference instances of Color objects instead of different types.
public static Color AliceBlue {get;}
Please note that a static class is a sealed class that contains only static members and cannot be instantiated using the new keyword as it can only have a private default constructor (at least in C#).
Imagine you are creating an API that takes Color as an argument, what will it look like if the Color is a static class?
One can argue that different colors should be different types (arguably static as well) instead of different instances of the Color class. Even with this case, Color should not be a static class because you want to have a base Color class for individual Color classes and making the base Color class static automatically makes it sealed.
One may still want to argue that Color should be a namespace and individual colors should be static classes. I will simply ask them to imagine what the API will look like again :)
Because a sealed class with all static members and private constructor constitutes certain performance enhancements because of the way the IL is formed for the use of the static class versus the sealed class, in-fact the static class gets the abstract modifier in IL to prevent new from being called where as the sealed class does not.
See.. This post on msdn social

Categories