Static classes inheriting from abstract classes? - c#

So I have a class A. It defines a lot of the behaviour (methods), but also leaves a lot to the subclasses to implement. This class is never going to have an instance. This is just going to define the behaviour that is common to all subclasses.
The subclasses (A1, A2, A3, etc.) that are going to extend A are all going to be singletons. I don't want these subclasses to have multiple instances.
So the obvious way to do this would be create an abstract class A and then static classes A1, A2, A3 that extend A.
But apparently, this isn't allowed in C#. I'm assuming there is a good reason for this. People at Microsoft probably know a lot more about objected-oriented software design than I do.
But I just need some help in figuring out why this design is "poor" and what would be an alternate better design.
I'm writing a RESTful API using WCF. There is a bunch of database tables that this service is going to perform CRUD operations on. There is a lot of code that is going to be common to all tables and a lot of code that is going to be specific to each table. Also, only one operation can be performed on the table at any given time.
So I thought I could have an abstract class TableHandler. And then multiple extensions of it such as TableAHandler, TableBHandler etc. Since I only want one instance of these subclasses, I wanted to make them static.

Inheritance is something that affects objects. By definition, static classes do not allow instantiation. Therefore, they can't be involved in inheritance.
More practically, static methods can't be virtual, which pretty much eliminates any possible usefulness of being able to declare inherited static classes.

Create a normal class that extends your base but follow the singleton pattern with a private constructor and static accessor to the instance.
abstract class A { }
class A1 : A
{
private static A1 instance;
public static A1 Instance
{
get
{
if( instance == null )
instance = new A1();
return instance;
}
}
private A1() { }
}
As noted by #ScottChamberlain, this implementation is not thread-safe. Using a static constructor will make the initialization thread-safe. More information can be found in this question: Is the C# static constructor thread safe?

Simplest way to define singleton pattern is Lazy<T>:
public abstract class A { }
public class B : A
{
private static Lazy<B> _instance = new Lazy<B>(() => new B());
private B() { }
public static B Instance
{
get
{
return _instance.Value;
}
}
}
This will also provide thread-safety to creation of your singleton.

Related

How to understand which class uses composition?

I don't understand the difference between these cases of "composition" in c#, could anyone explain?
class B
{
}
example 1:
class A : IDisposable
{
private B objB;
public A(){objB = new B();}
public void Dispose(){}
}
example 2:
class A : IDisposable
{
private B objB;
public A(B obj){this.objB = obj;}
public void Dispose(){}
}
example 3:
class A : IDisposable
{
private B objB;
public A(){}
public void Sample(){objB = new B();}
public void Dispose(){}
}
I know that one is not the composition, but I don't understand why.
Also, is there a difference in cases:
class B : IDisposable
{
//is there a difference if I will and won't implement the methods of the interface?
}
class A : IDisposable
{
public B objB {get;set;}
public A(){}
public void Sample(){}
public void Dispose(){}
}
So my questions about composition: 1) Is there a difference if the B in A is private or public? 2) Do I have to initialize the B in A to count it as a composition? If so, is there any difference in what way I will do this? 3) Can I use composition if both my classes implement the same interface, but one of them doesn't implement its methods? (the last example).
Thanks for the answers!
All are examples of composition, at least in the sense of composition vs inheritance. A useful memonic is that composition has a and inheritance is a. I.e. A has a B. On the other hand A is a IDisposable.
There is also composition vs aggregation. In this sense composition owns a while aggregation uses a. Example 1 and 3 are clear examples of ownership. For example 2 it is unclear, in some cases a constructor parameter might imply taking ownership of the object, in other cases it might not, and in some cases there is a separate parameter to decide if ownership should be transferred or not. In any case, "Ownership" usually only matters if the the object is IDisposable, so in this trivial example it is not really useful to talk aggregation vs composition.
The examples rather show different way to take dependencies, if the object B is required for the correct functioning of the object A, then A depends on B.
Example 1 is simply creating its dependency, and is typical when depending on 'simple' objects, like a list.
Example 2 can be called dependency injection, and is usually a good idea for more complex object hierarchies.
Example 3 could be called Initialization. I.e. your Sample-method is initializing the object, and must be called before the object can be used. I would try to avoid this, since it is easy to forget to call the initialization method. It is typically easier
Your last example would be of an optional property. I.e. A should work just fine if objB is not set by anyone, but may change its behavior if it is set.
To me this is a rater poor question. I do not think I have ever discussed composition vs aggregation, and composition vs inheritance is usually mentioned to advocate against inheritance. I suspect the real point is regarding lifetimes and disposal. Any disposable object needs to be disposed, and it should always be clear who is responsible for disposing the object. A somewhat common pattern is something like this:
public class MyClass : IDisposable{
public MyDependency dep;
public suppressDispose;
public MyClass(MyDependency dep, bool suppressDispose = false) => (dep, suppressDispose ) = (dep, suppressDispose );
public void Dispose(){
if(!suppressDispose) dep.Dispose();
}
}
That takes over ownership by default, but allow for an opt out if the dependency need to be used later.

Does making singleton class sealed really help in achieving goal of singleton pattern C# - Static Initialization (A thread safe solution)

I know other threads exist regarding this question but I couldn't find satisfactory answer for this. Why singleton class needs to be sealed in C# ? (To clarify my question)Does making it sealed really help it achieving goal of singleton (only one instance) ?
I have added more clarification about what I am wanting to know and trying to find reason for, hope readers understand what I am trying to discuss.
I am talking about MSDN article's thread safe solution :
https://msdn.microsoft.com/en-us/library/ff650316.aspx.
In this article first they give solution which is not thread safe, then they give another solution using static initialization to make it thread safe and in that solution they make class: sealed
As per MSDN's explanation -- The class is marked sealed to prevent derivation, which could add instances. For a discussion of the pros and cons of marking a class sealed, see [Sells03].
When I tried to figure why they used Sealed in static initialization approach, only thing I could figure is: as they wanted to prevent additional instantiation they made it sealed (this only prevents instantiation done through derivation, nested sub class derivation could create additional instances but by using Sealed it doesn't prevent nested class from creating additional instances.) to achieve goal of singleton. If using sealed doesn't prevent additional instantiation through other ways then why use it ?
Below is the MSDN's thread safe solution:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
My question is does MSDN's thread safe solution achieve goal of singleton by making it sealed? They made class sealed to prevent instantiation through derivation but that doesn't stop instantiation done through other ways. See my example below:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton() { }
public static Singleton Instance
{
get
{
return instance;
}
}
public class nestedSingleton
{
public nestedSingleton()
{
Singleton moreThanOneObject = new Singleton();
}
}
}
Simply put: if anyone can derive from it, there can be multiple instances. So you definitely need some way of preventing arbitrary derivation.
Now you can simply rely on a private constructor to prevent subclassing instead (and you need the private constructor anyway), but the only reason for making a Singleton class unsealed would be if you wanted a nested type to be the implementation, e.g.
public class Singleton
{
public static Singleton Instance { get; }
= (DateTime.Now.Seconds & 1) == 0
? (Singleton) new EvenSingleton() : new OddSingleton();
private Singleton() {}
private class OddSingleton : Singleton {}
private class EvenSingleton : Singleton {}
}
This is properly a singleton - but it's a pretty unusual situation. It's vastly more common not to need a nested type to be the implementation, at which point it's clearer IMO to seal the singleton to make it clearer that you don't intend there to be any subclasses.
Basically it's communication as much as anything - a sealed class clearly prohibits derivation, whereas just having the private constructor (but no nested types) makes it more implicit. I think being explicit is clearer.
(Also, in earlier versions of C#, there are some bizarre ways you can get subclasses to compile with mutually recursive constructor calls so you never end up with a base constructor initializer. This has now been fixed, fortunately.)
To respond to a question addition:
Sealed keyword doesnt even make sense in this case if MSDN added it to prevent creating more instances of singleton by Nested sub classes.
In the example you've given, the nested class isn't a subclass. It looks like this:
public class nestedSingleton
whereas a nested subclass would look like this:
public class nestedSingleton : Singleton
(except ideally following .NET naming conventions).
It does not have to be
Implementing Singleton in C#
This is not safe on multithreads but a singleton
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
Making it sealed would make it not possible to inherit it (eliminating a possible cause for several instances of a singleton)
The reason is very tied to implementation details.
For example, see the following simple and wrong singleton implementation in C#:
public class A
{
private static readonly A _instance;
static A()
{
_instance = new A();
}
public static A Instance => _instance;
public string Name { get; set; }
}
Now let's derive it into B:
public class B : A
{
public string Surname { get; set; }
}
What would happen if you call B.Current static property?
// ERROR! Surname isn't a property of A
string surname = B.Instance.Surname;
One of main drawbacks of not sealing a singleton class is that static members are still accessible on derived classes. That is, it's very confusing that you can access Instance property on B but it returns the singleton instance of A.
You can't take this risk and one simple and yet powerful way of avoiding confusion is sealing A. Since A is a singleton implementation, you don't want to be inheritable, because derived classes can't expand the singleton.
If you're agree with the point of avoiding the described situation, a more convenient implementation of singleton could be:
// SEALED
public sealed class A
{
private static readonly A _instance;
// Avoid that other code excepting A class members
// can instantiate A
private A() {}
static A()
{
_instance = new A();
}
public static A Instance => _instance;
public string Name { get; set; }
}
About the criticism of using a static read-only field instead of lazy-loading the single instance...
I've also checked that some seem to be against my proposal of instantiating the single instance as part of static constructor or using a field initializer. I could also simplify the implementation as follows:
public sealed class A
{
private A() {}
private static readonly A _instance = new A();
public static A Instance => _instance;
public string Name { get; set; }
}
And, as far as I know, it provides more advantages than instantiating the single A instance in the Instance static property getter:
...
private static A _instance;
public static A Instance
{
get
{
if(_instance == null) _instance = new A();
return _instance;
}
}
See this other Q&A to understand that static constructors are thread-safe: Is the C# static constructor thread safe?
In response to my answer's criticism about my sample singleton implementation
In some comment, Jon Skeet has said:
A singleton doesn't just provide a single instance - it ensure that
it's the only instance ever created. See
en.wikipedia.org/wiki/Singleton_pattern "In software engineering, the
singleton pattern is a design pattern that restricts the instantiation
of a class to one object." Your code doesn't do that.
It's not a good argument to invalidate my sample implementation. For example, most inversion of control containers let you configure the life-cycle to singleton of a given component and its implementation.
The whole implementation is a regular public class with no constraint preventing you from even configuring the same implementation for other component, or you can even instantiate the implementation with new (i.e. new A()) wherever you want.
But the so-called component is a singleton, because you've configured that it will be a single instance of the whole component across the entire AppDomain.
Now let's see the Implementation section on Singleton pattern (Wikipedia):
Implementation of a singleton pattern must satisfy the single instance
and global access principles. It requires a mechanism to access the
singleton class member without creating a class object and a mechanism
to persist the value of class members among class objects. The
singleton pattern is implemented by creating a class with a method
that creates a new instance of the class if one does not exist. If an
instance already exists, it simply returns a reference to that object.
To make sure that the object cannot be instantiated any other way, the
constructor is made private. Note the distinction between a simple
static instance of a class and a singleton: although a singleton can
be implemented as a static instance, it can also be lazily
constructed, requiring no memory or resources until needed.
Comparing this implementation description with my sample implementation, I would say that the following implementation is a singleton:
public sealed class A
{
private A() {}
private static readonly A _instance = new A();
public static A Instance => _instance;
public string Name { get; set; }
}
You can't publicly instantiate it.
It can be only a single instance within a given AppDomain.
It provides global access to itself.
It implements a method to create the single instance, but it's using C# specific syntax and syntactic sugar.
It's lazily instantiated when the static Instance property is first instantiated. This is how static constructors and static class field initializers work in C#.
Now let's analyze the inversion of control container case:
Usually components are defined by interfaces and abstract classes. Few times are concrete classes. Thus, you can't instantiate an abstract class or interface.
There's no Instance static property, but the implementation description on Wikipedia says: [...] It requires a mechanism to access the singleton class member without creating a class object and a mechanism to persist the value of class members among class objects. The fact that you can implement this with an Instance static property of singleton class is just an implementation detail on some programming languages. The pattern description is fine with how inversion of control containers work. Either something like service locator anti-pattern or just dependency injection, are mechanisms that provide the single instance.
With inversion of control containers you can access singletons globally. For example, Container.Resolve<ISomeComponentConfiguredAsSingleton>(). BTW, excepting on few cases, service locator is considered an anti-pattern.
Most inversion of control containers can provide custom factories where you can define how the component implementation will be instantiated.
Based on previous point, you can easily implement a factory with lazy-loading.
In summary, I would say that in my particular case I've already left my ortodoxy and I assume that design patterns are abstract definitions to implement solutions to common problems and most are and should be language-agnostic. As long as my code works as the description of a given design pattern for me is enough to consider I'm implementing the whole design pattern. You can even implement singleton without calling your class WhateverSingleton.

Adding private method to class by inheritance in C#

I asked this question yesterday, but I think it was unclear what my primary concern was. In C++, we have private and multiple inheritance, which enables us to add private methods to classes by just inheriting from the class declaring these methods. That is, if there's a class
class B {
public:
virtual void doMethodB();
};
and a class
class A : private B {
virtual int doMethodA();
};
doMethodB() can be called from within doMethodA(), but is not accessible from outside.
Now, I'd like to mimic this behavior in C#. There is no multiple nor private inheritance. Up to know, I can think of four way to achieve somthing similar, but still with serious drawbacks:
First: Use an interface, i.e.
interface IB {
public void doMethodB();
};
class A : IB {
public void doMethodB();
int doMethodA();
};
However, when we do this, doMethodB() is public, and must be implemented in each class inheriting from IB.
Second: Use a static method
public static class B {
public static void doMethodB();
};
That way, there need only be one implementation, but the method is still public and can't be restricted to certain classes.
Third: Use a extension method, like that. That way however, the method is called on the object (i.e. a.doMethodB()) and not from "inside".
Fourth: Composition.
class A {
private B b;
public int doMethodA();
};
Now, B's methods can be called like b.doMethodB() from A only, but are other issues now regarding serialization, b == null etc.
Is there another alternative? And if not, which one among the presented ones would you consider "the best"?
Regarding your "First" proposal with interfaces: you can also implement the interface explicitly:
"A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface. "
See / Source: http://msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx
However, i would choose the Composition approach. "Favor Composition over Inheritance", also see Prefer composition over inheritance?
Ideally, i would constructor-inject B into A by dependency injection, that should help mitigate your b == null concern.
Note:
Using a static method / extension method (is a static method, too...) makes unit-testing A (respectively faking B) very hard, which is why i would forgo these solutions completely.
Edit:
If you don't need B.doMethodB accessible from anyone else than A, you can also make B an abstract class and B.doMethodB a protected method.
But i was thinking that you already know that ;-)
(And because of the testing issues i would still favor composition over inheritance).
I think the concept you are looking for is the protected access modifier. It means that only B itself and its derived classes can access the method, but others cannot.
class B {
protected virtual void DoMethodB() {}
}
class A : B {
virtual void DoMethodA() {
DoMethodB();
}
}
If you wanted, you can further restrict the access to protected internal which means that the method can only be accessed from derived classes inside your assembly.
Also, be aware of the consequences of virtual methods. If there is no explicit need to make a method virtual, it should not be marked virtual.

C# class design - what can I use instead of "static abstract"?

I want to do the following
public abstract class MyAbstractClass
{
public static abstract int MagicId
{
get;
}
public static void DoSomeMagic()
{
// Need to get the MagicId value defined in the concrete implementation
}
}
public class MyConcreteClass : MyAbstractClass
{
public static override int MagicId
{
get { return 123; }
}
}
However I can't because you can't have static abstract members.
I understand why I can't do this - any recommendations for a design that will achieve much the same result?
(For clarity - I am trying to provide a library with an abstract base class but the concrete versions MUST implement a few properties/methods themselves and yes, there are good reasons for keeping it static.)
You fundamentally can't make DoSomeMagic() work with the current design. A call to MyConcreteClass.DoSomeMagic in source code will be translated into MyAbstractClasss.DoSomeMagic in the IL. The fact that it was originally called using MyConcreteClass is lost.
You might consider having a parallel class hierarchy which has the same methods but virtual - then associate each instance of the original class with an instance of the class containing the previously-static members... and there should probably only be one instance of each of those.
Would the Singleton pattern work perhaps? A link to the MSDN article describing how to implement a singleton in C#:
http://msdn.microsoft.com/en-us/library/ff650316.aspx
In your particular example, the Singelton instance could extend an abstract base class with your MagicId in it.
Just a thought :)
I would question that there are "good reasons" for making the abstract members static.
If your thinking is that these members might reflect some property of the derived class itself rather than a given instance, this does not necessarily mean the members should be static.
Consider the IList.IsFixedSize property. This is really a property of the kind of IList, not any particular instance (i.e., any T[] is going to be fixed size; it will not vary from one T[] to another). But still it should be an instance member. Why? Because since multiple types may implement IList, it will vary from one IList to another.
Consider some code that takes any MyAbstractClass (from your example). If this code is designed properly, in most cases, it should not care which derived class it is actually dealing with. What matters is whatever MyAbstractClass exposes. If you make some abstract members static, basically the only way to access them would be like this:
int magicId;
if (concreteObject is MyConcreteClass) {
magicId = MyConcreteClass.MagicId;
} else if (concreteObject is MyOtherConcreteClass) {
magicId = MyOtherConcreteClass.MagicId;
}
Why such a mess? This is much better, right?
int magicId = concreteObject.MagicId;
But perhaps you have other good reasons that haven't occurred to me.
Your best option is to use an interface with MagicId only using a setter
public interface IMagic
{
int MagicId { get; }
}
By the nature of Static meaning there can only be one (yes like Highlander) you can't override them.
Using an interface assumes your client will implement the contract. If they want to have an instance for each or return the value of a Static variable it is up to them.
The good reason for keeping things static would also mean you do NOT need to have it overridden in the child class.
Not a huge fan of this option but...
You could declare the property static, not abstract, virtual and throw a NotImplementedException which returns an error message that the method has to be overridden in a derived class.
You move the error from compile time to run time though which is kinda ugly.
Languages that implement inheritance of static members do it through metaclasses (that is, classes are also objects, and these objects have a metaclass, and static inheritance exists through it). You can vaguely transpose that to the factory pattern: one class has the magic member and can create objects of the second class.
That, or use reflection. But you can't ensure at compile-time that a derived class implements statically a certain property.
Why not just make it a non-static member?
Sounds like a Monostate, perhaps? http://c2.com/cgi/wiki?MonostatePattern
The provider pattern, used by the ASP.NET membership provider, for example, might be what you're looking for.
You cannot have polymorphic behavior on static members, so you'll have a static class whose members delegate to an interface (or abstract class) field that will encapsulate the polymorphic behaviors.

Why can't I inherit static classes?

I have several classes that do not really need any state. From the organizational point of view, I would like to put them into hierarchy.
But it seems I can't declare inheritance for static classes.
Something like that:
public static class Base
{
}
public static class Inherited : Base
{
}
will not work.
Why have the designers of the language closed that possibility?
Citation from here:
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)
Other opinions from channel9
Inheritance in .NET works only on instance base. Static methods are defined on the type level not on the instance level. That is why overriding doesn't work with static methods/properties/events...
Static methods are only held once in memory. There is no virtual table etc. that is created for them.
If you invoke an instance method in .NET, you always give it the current instance. This is hidden by the .NET runtime, but it happens. Each instance method has as first argument a pointer (reference) to the object that the method is run on. This doesn't happen with static methods (as they are defined on type level). How should the compiler decide to select the method to invoke?
(littleguru)
And as a valuable idea, littleguru has a partial "workaround" for this issue: the Singleton pattern.
The main reason that you cannot inherit a static class is that they are abstract and sealed (this also prevents any instance of them from being created).
So this:
static class Foo { }
compiles to this IL:
.class private abstract auto ansi sealed beforefieldinit Foo
extends [mscorlib]System.Object
{
}
Think about it this way: you access static members via type name, like this:
MyStaticType.MyStaticMember();
Were you to inherit from that class, you would have to access it via the new type name:
MyNewType.MyStaticMember();
Thus, the new item bears no relationships to the original when used in code. There would be no way to take advantage of any inheritance relationship for things like polymorphism.
Perhaps you're thinking you just want to extend some of the items in the original class. In that case, there's nothing preventing you from just using a member of the original in an entirely new type.
Perhaps you want to add methods to an existing static type. You can do that already via extension methods.
Perhaps you want to be able to pass a static Type to a function at runtime and call a method on that type, without knowing exactly what the method does. In that case, you can use an Interface.
So, in the end you don't really gain anything from inheriting static classes.
Hmmm... would it be much different if you just had non-static classes filled with static methods..?
What you want to achieve by using class hierarchy can be achieved merely through namespacing. So languages that support namespapces ( like C#) will have no use of implementing class hierarchy of static classes. Since you can not instantiate any of the classes, all you need is a hierarchical organization of class definitions which you can obtain through the use of namespaces
You can use composition instead... this will allow you to access class objects from the static type. But still cant implements interfaces or abstract classes
Although you can access "inherited" static members through the inherited classes name, static members are not really inherited. This is in part why they can't be virtual or abstract and can't be overridden. In your example, if you declared a Base.Method(), the compiler will map a call to Inherited.Method() back to Base.Method() anyway. You might as well call Base.Method() explicitly. You can write a small test and see the result with Reflector.
So... if you can't inherit static members, and if static classes can contain only static members, what good would inheriting a static class do?
A workaround you can do is not use static classes but hide the constructor so the classes static members are the only thing accessible outside the class. The result is an inheritable "static" class essentially:
public class TestClass<T>
{
protected TestClass()
{ }
public static T Add(T x, T y)
{
return (dynamic)x + (dynamic)y;
}
}
public class TestClass : TestClass<double>
{
// Inherited classes will also need to have protected constructors to prevent people from creating instances of them.
protected TestClass()
{ }
}
TestClass.Add(3.0, 4.0)
TestClass<int>.Add(3, 4)
// Creating a class instance is not allowed because the constructors are inaccessible.
// new TestClass();
// new TestClass<int>();
Unfortunately because of the "by-design" language limitation we can't do:
public static class TestClass<T>
{
public static T Add(T x, T y)
{
return (dynamic)x + (dynamic)y;
}
}
public static class TestClass : TestClass<double>
{
}
You can do something that will look like static inheritance.
Here is the trick:
public abstract class StaticBase<TSuccessor>
where TSuccessor : StaticBase<TSuccessor>, new()
{
protected static readonly TSuccessor Instance = new TSuccessor();
}
Then you can do this:
public class Base : StaticBase<Base>
{
public Base()
{
}
public void MethodA()
{
}
}
public class Inherited : Base
{
private Inherited()
{
}
public new static void MethodA()
{
Instance.MethodA();
}
}
The Inherited class is not static itself, but we don't allow to create it. It actually has inherited static constructor which builds Base, and all properties and methods of Base available as static. Now the only thing left to do make static wrappers for each method and property you need to expose to your static context.
There are downsides like the need for manual creation of static wrapper methods and new keyword. But this approach helps support something that is really similar to static inheritance.
P.S.
We used this for creating compiled queries, and this actually can be replaced with ConcurrentDictionary, but a static read-only field with its thread safety was good enough.
My answer: poor design choice. ;-)
This is an interesting debate focused on syntax impact. The core of the argument, in my view, is that a design decision led to sealed static classes. A focus on transparency of the static class's names appearing at the top level instead of hiding ('confusing') behind child names? One can image a language implementation that could access the base or the child directly, confusing.
A pseudo example, assuming static inheritance was defined in some way.
public static class MyStaticBase
{
SomeType AttributeBase;
}
public static class MyStaticChild : MyStaticBase
{
SomeType AttributeChild;
}
would lead to:
// ...
DoSomethingTo(MyStaticBase.AttributeBase);
// ...
which could (would?) impact the same storage as
// ...
DoSomethingTo(MyStaticChild.AttributeBase);
// ...
Very confusing!
But wait! How would the compiler deal with MyStaticBase and MyStaticChild having the same signature defined in both? If the child overrides than my above example would NOT change the same storage, maybe? This leads to even more confusion.
I believe there is a strong informational space justification for limited static inheritance. More on the limits shortly. This pseudocode shows the value:
public static class MyStaticBase<T>
{
public static T Payload;
public static void Load(StorageSpecs);
public static void Save(StorageSpecs);
public static SomeType AttributeBase
public static SomeType MethodBase(){/*...*/};
}
Then you get:
public static class MyStaticChild : MyStaticBase<MyChildPlayloadType>
{
public static SomeType AttributeChild;
public static SomeType SomeChildMethod(){/*...*/};
// No need to create the PlayLoad, Load(), and Save().
// You, 'should' be prevented from creating them, more on this in a sec...
}
Usage looks like:
// ...
MyStaticChild.Load(FileNamePath);
MyStaticChild.Save(FileNamePath);
doSomeThing(MyStaticChild.Payload.Attribute);
doSomething(MyStaticChild.AttributeBase);
doSomeThing(MyStaticChild.AttributeChild);
// ...
The person creating the static child does not need to think about the serialization process as long as they understand any limitations that might be placed on the platform's or environment's serialization engine.
Statics (singletons and other forms of 'globals') often come up around configuration storage. Static inheritance would allow this sort of responsibility allocation to be cleanly represented in the syntax to match a hierarchy of configurations. Though, as I showed, there is plenty of potential for massive ambiguity if basic static inheritance concepts are implemented.
I believe the right design choice would be to allow static inheritance with specific limitations:
No override of anything. The child cannot replace the base
attributes, fields, or methods,... Overloading should be ok, as
long as there is a difference in signature allowing the compiler to
sort out child vs base.
Only allow generic static bases, you cannot inherit from a
non-generic static base.
You could still change the same store via a generic reference MyStaticBase<ChildPayload>.SomeBaseField. But you would be discouraged since the generic type would have to be specified. While the child reference would be cleaner: MyStaticChild.SomeBaseField.
I am not a compiler writer so I am not sure if I am missing something about the difficulties of implementing these limitations in a compiler. That said, I am a strong believer that there is an informational space need for limited static inheritance and the basic answer is that you can't because of a poor (or over simple) design choice.
Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. Static class members can be used to separate data and behavior that is independent of any object identity: the data and functions do not change regardless of what happens to the object. Static classes can be used when there is no data or behavior in the class that depends on object identity.
A class can be declared static, which indicates that it contains only static members. It is not possible to use the new keyword to create instances of a static class. Static classes are loaded automatically by the .NET Framework common language runtime (CLR) when the program or namespace that contains the class is loaded.
Use a static class to contain methods that are not associated with a particular object. For example, it is a common requirement to create a set of methods that do not act on instance data and are not associated to a specific object in your code. You could use a static class to hold those methods.
Following are the main features of a static class:
They only contain static members.
They cannot be instantiated.
They are sealed.
They cannot contain Instance Constructors (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 have a static constructor. For more information, see Static Constructors (C# Programming Guide).
When we create a static class that contains only the static members and a private constructor.The only reason is that the static constructor prevent the class from being instantiated for that we can not inherit a static class .The only way to access the member of the static class by using the class name itself.Try to inherit a static class is not a good idea.
I run into the problem when trying to code an IComparer<T> implementation against a third-party library where T is an enum embedded in a class as in the following:
public class TheClass
{
public enum EnumOfInterest
{
}
}
But because the enum is defined within a third-party library class, I can't write the comparer because the following gives a "cannot extends list" error:
public class MyComparer : IComparer<TheClass.EnumOfInterest>
{
}
I'm not even extending a static class -- I'm just implementing a comparer of a enum defined in a class.

Categories

Resources