I just came up with a really odd problem and I wasn't able to figure out how to solve it.
I have 3 classes, the class A is the base for B and C, that is:
class A { ... }
class B : A { ... }
class C : B { ... }
Now I would like to have a static property in these classes that stores the last object of each classes created, for example:
class A
{
static public A lastInstance;
}
class B : A
{
public B()
{
lastInstance = this;
}
}
class C : A
{
public C()
{
lastInstance = this;
}
}
What I would like to achieve is to be able to retrieve an instance for each subclass, for example:
var v1 = new B();
var v2 = new C();
var v3 = B.lastInstance; // v3 == v1 and v3 != v2
var v4 = C.lastInstance; // v4 == v2 and v4 != v3
Is it possible anyhow?
The only approach that seems promising to me shown in C# Static instance members for each inherited class: is it really the only chance I have to avoid defining a static member manually for each class?
I think this could be done with Dictionary
and that's the only way i can think of right now:
class A {
static Dictionary<Type, A> _LastInstances = new Dictionary<Type, A>(); // because every subclass will inherit from A
public static A LastInstance {
get {
if ( _LastInstances.ContainsKey(GetType()) ) {
return _LastInstances[GetType()];
}
return null;
}
protected set {
if ( _LastInstances.ContainsKey(GetType()) ) {
_LastInstances[GetType()] = value;
} else {
_LastInstances.Add(GetType(), value);
}
}
}
class B : A {
public B(){
LastInstance = this;
}
}
At first: yes you can. But you missed two points with your implementation.
- As you declared the
lastInstance
as public in class A every derived class can use it. As you declared it as static every instance of A will copy itself into it. But so will every instance of B, C and every other class with id derived from A: they all use the same instance. Thus the last instatiated class is saved and everything instantiated before is overwritten.
To overcome this, you must have a static property LastInstance
(I switched to my naming convention) on every class, which you can accomplish by using the new
modifier on derived classes
public class A
{
public static A LastInstance { get; private set; }
...
}
public class B : A
{
public static new B LastInstance { get; private set; }
...
}
But you're not done with that alone, because
- When you create a new instance of B the (default-)construstor first makes a call into the construtor of A. Thus a reference to any already created instance of a base class is overwritten by the currently created instance of the derived class. So your constructors should look like this:
public class A
{
public static A LastInstance { get; private set; }
public A()
{
if (this.GetType() == typeof(A))
{
LastInstance = this;
}
}
}
public class B : A
{
public static new B LastInstance { get; private set; }
public B()
{
if (this.GetType() == typeof(B))
{
LastInstance = this;
}
}
}
This way you will get the correct lastly created instance (if any) in each classes static LastInstance
.
Hope this helps
Because static members aren't inherited, you won't be able to access B.lastInstance if class A defines lastInstance. The suggestion you linked to seems reasonable. Although I don't have enough information on why you're attempting this, you could consider using a factory class that holds onto the latest created object.
Here's an example. This is not a good long term solution if you plan to have many classes deriving from A.
class HoldLastKnownFactory
{
B CreateB() { ... }
C CreateC() { ... }
B LastB { get {...} }
C LastC { get {...} }
}