Deriving static members - c#

I have a base class that has a private static member:
class Base
{
private static Base m_instance = new Base();
public static Base Instance
{
get { return m_instance; }
}
}
And I want to derive multiple classes from this:
class DerivedA : Base {}
class DerivedB : Base {}
class DerivedC : Base {}
However, at this point calling DerivedA::Instance will return the same exact object as will DerivedB::Instance and DerivedC::Instance. I can solve this by declaring the instance in the derived class, but then every single derived class will need to do that and that just seems like it should be unneccessary. So is there any way to put all this in the base class? Could a design pattern be applied?

There's one really icky way of doing this:
class Base
{
// Put common stuff in here...
}
class Base<T> : Base where T : Base<T>, new()
{
private static T m_instance = new T();
public static T Instance { get { return m_instance; } }
}
class DerivedA : Base<DerivedA> {}
class DerivedB : Base<DerivedB> {}
class DerivedC : Base<DerivedC> {}
This works because there's one static variable per constructed type - e.g. List<string> is a different type to List<int> and so would have separate static variables.
I've taken the opportunity of making it an instance of the derived class as well - I don't know whether that's what you want or not, but I thought I'd at least make it available for you :)
In general though, this is a nasty thing to do. Static variables aren't really designed for this kind of use - I've just abused a feature of generics to get "sort of" the behaviour you asked for.
Also note that Base<DerivedA>.Instance will return the same result as DerivedA.Instance - the property/variable don't "know" that you're using DerivedA.Instance. I don't know whether or not that's important to you.
With the extra non-generic class, you can write:
Base t = DerivedA.Instance;
t = DerivedB.Instance;
If you don't need that, take it out :)

Static methods does not support polymorphism, therefore, such a thing is not possible.
Fundamentally, the Instance property has no idea how you're using it. And a single implementation of it will exist, as it's static. If you really wanted to do this, this "not recommended" solution is available (I got the idea from Jon's solution):
private static Dictionary<Type, Base> instances = new Dictionary<Type, Base>();
public static T GetInstance<T>() where T : Base, new() {
Type ty = typeof(T);
T x;
if (instances.TryGetValue(ty, out x)) return x;
x = new T();
instances[ty] = x;
return x;
}

Short answer: not that I'm aware of. Static members are always nonvirtual and do not readily support polymorphism.
However, you should also ask yourself why you are doing this. Normally, static members are shared resources that every instance of that class (including the derived classes) will find useful. However, when you make a static instance, you are usually building towards a singleton pattern. In this case, you usually want to seal the class so you can't have derived classes, thus rendering the entire point moot. Thus, you should really be analyzing why you are wanting to do this and solve that problem instead.

Related

Design pattern for overcoming the reverse constructor order?

I have the following problem:
The base class expects to receive some data but the data is initialized by the derived class constructor which in C# is called after the base constructor was called.
Context / What I'm trying to solve:
Let's call the base class Track, its role is to build a mesh that represents a track for a video game.
The derived classes, e.g. Track1 each fetch track data from a particular file format, with significant differences that forbids implementing the whole code in base class Track.
The main job of Track is to abstract the data incoming from derived classes and for this it has abstract members that derived classes have to implement, e.g. int GetVertexCount, Vector3 GetVertex(int).
Think more of less of it being an IPicture interface that can load from different formats, e.g. BMP, JPEG, and return the whole thing as an abstraction.
The problem I am facing:
In C#, base class constructors are called before derived class constructor, but I must initialize something in the derived class constructor that in turn I must pass to the base class constructor. And while I'm on it, I would like to have members to be immutable, i.e. readonly.
Question:
How can I run some code in derived class constructor first, so I can pass the result to the base constructor ?
Answer:
Following #Kit answer here's how I ended up doing and it's just fine:
Ironically, it ended up being a C-like API :)
Assuming you don't need an instance of your derived class to do the logic you want, you can call a static method from your derived constructor prior to calling the base constructor.
Here is a simplistic example
public class Base
{
protected Base(SomeType data)
{
// base logic using data
}
}
public class DerivedOne : Base
{
public DerivedOne(int some, string data) : base(DerivedLogic(some, data))
{
...
}
private static SomeType DerivedLogic(int some, string data) => ...
}
public class DerivedTwo : Base
{
public DerivedTwo (string moreStuff) : base(DerivedLogic(moreStuff))
{
...
}
private static SomeType DerivedLogic(string moreStuff) => ...
}
This runs in the following order:
Static method DerivedLogic
Base class constructor (using the value from DerivedLogic)
Derived constructor
Now, that's slightly weird. What might be better is the derived logic not be a part of the derived class at all. What do I mean? I mean you have a third class that is passed into the derived constructor, and then on to the base constructor. That gives you the same effect.
public class Base
{
protected Base(SomeOtherType dataWrapper)
{
var data = dataWrapper.DerivedLogic();
// base logic using data
}
}
public class DerivedOne : Base
{
public DerivedOne(SomeOtherType otherType) : base(otherType)
{
...
}
}
Or calculate SomeType somewhere prior to calling any constructors and then pass it in. Either of these ways is a better design because it follows SRP:
Base class responsible for what it does.
Logic for constructing a track has that single responsibility.
Derived class has it's single responsibility.
There's not a really elegant way to do exactly what you're asking for, but I would question whether it's really necessary. It's usually a code smell to see logic in a constructor.
There are lots of other approaches you can take, like using a static Create() method.
class Derived : Base
{
private readonly object _o;
private Derived(object o, string s) : base(s)
{
_o = o;
}
public static Derived Create(string path)
{
var o = new object();// initialize from path
var s = o.ToString(); // get s from o.
return new Derived(o, s)
}
}
You could also consider using composition over inheritance:
class Base
{
private readonly string _s;
public Base(string s)
{
_s = s.ToLower();
}
}
class Derived
{
private readonly object _o;
private readonly Base _b;
public Derived(string path)
{
_o = new object();// initialize from path
_b = new Base(_o.ToString());
}
}
But it's really difficult to know which of these approaches might be appropriate without knowing what your actual goals and constraints are. You've told us how you want to solve your problem, and not what problem you're trying to solve.

Preventing inheritance of static member

Base:
public abstract class systemClient : IDisposable
{
public static List<systemClient> Collection = new List<systemClient>();
[...]
}
derived class
public class station : systemClient
{
[...]
}
In this setup I can access station.Collection.
Question is:
Is there a way to hide station.Collection ?
You can't. By creating inhClass as a subclass of baseClass inhClass must provide everything that baseClass provides. Otherwise baseClass x = new inhClass() would be invalid.
In this specific case though you have made the method static, that means that it doesn't actually have its own copy of the method. inhClass is just accessing the static one within baseClass.
I agree with Tim B answer. You can't simply "ignore" some methods or properties of a class which you inherits. But, what you can do is implementing an interface, which may do the work you want. For further reading, take a look here.

Why this works in C# (generic class and self-reference)?

I have
class X<T> : Base
{
//For exemple:
static T something();
}
And I can have
class A : X <A>
{
}
To logically have something like this:
class A : Base
{
static A something();
}
This works and works well.
But in my comprehension, it's kind of self-reference (A is the children of X, while X doesn't exists before A...), which is breaks the foundation of computer science, so I want to know what's wrong with my comprehension??
It's totally fine. You can do similar without generics too:
class Test
{
public static Test GetInstance()
{
return new Test();
}
}
I don't see any self-reference here. And actually it's quite useful pattern e.g. when implementing singletons. Simplified concept (I know, it should use locks, etc...):
public static class Singleton<T> where T : new()
{
private static T _instance;
public static T GetInstance()
{
return _instance ?? (_instance = new T());
}
}
Edit - Answering your comment question:
X<T> already exists for all suitable T parameters. By suitable I mean every type that suits generic constraint (or just every type when there is no constraint). And by every I mean not only all classes available within your assembly. Just every suitable type.
Generic class/method is just a template which is resolved for given particular generic type in runtime. That's why you don't have to even use the generic class at all in assemble it's declared within. And that's why your code works fine.

derived instance in base class

class baseClass
{
derivedClass nm = new derivedClass();
}
class derivedClass : baseClass
{
}
This code builds fine. What might be the possible reason for C# to allow creating derivedClass objects in baseClass. Can you think of any specific reasons for doing this?
This code builds fine.
Yes - why do you think it wouldn't?
What might be the possible reason for C# to allow creating derivedClass objects in baseClass.
Because there's no reason to prohibit it?
Can you think of any specific reasons for doing this?
Static factory methods, for example?
// BaseClass gets to decide which concrete class to return
public static BaseClass GetInstance()
{
return new DerivedClass();
}
That's actually a pretty common pattern. We use it a lot in Noda Time for example, where CalendarSystem is a public abstract class, but all the concrete derived classes are internal.
Sure, it's crazy to have the exact example you've given - with an instance field initializing itself by creating an instance of a derived class - because it would blow up the stack due to recursion - but that's not a matter of it being a derived class. You'd get the same thing by initializing the same class:
class Bang
{
// Recursively call constructor until the stack overflows.
Bang bang = new Bang();
}
A developer I used to work with produced this code in our codebase. I personally agree its useful.
public class Foo
{
public static Foo MagicalFooValue
{
get { return Bar.Instance; }
}
private class Bar : Foo
{
//Implemented as a private singleton
}
}
One obvious case is to have a factory method in the base class returning appropriate implementations based on some condition.
derivedClass can be instantiated in baseClass because it is an accessible class. There is no reason why c# should restrict you from doing so. Likewise, you can create an instance of baseClass within baseClass itself.

C#: Determine derived object type from a base class static method

In a C# program, I have an abstract base class with a static "Create" method. The Create method is used to create an instance of the class and store it locally for later use. Since the base class is abstract, implementation objects will always derive from it.
I want to be able to derive an object from the base class, call the static Create method (implemented once in the base class) through the derived class, and create an instance of the derived object.
Are there any facilities within the C# language that will allow me to pull this off. My current fallback position is to pass an instance of the derived class as one of the arguments to the Create function, i.e.:
objDerived.Create(new objDerived(), "Arg1", "Arg2");
Try using generics:
public static BaseClass Create<T>() where T : BaseClass, new()
{
T newVar = new T();
// Do something with newVar
return T;
}
Sample use:
DerivedClass d = BaseClass.Create<DerivedClass>();
Summary
There are two main options. The nicer and newer one is to use generics, the other is to use reflection. I'm providing both in case you need to develop a solution that works prior to .NET 2.0.
Generics
abstract class BaseClass
{
public static BaseClass Create<T>() where T : BaseClass, new()
{
return new T();
}
}
Where the usage would be:
DerivedClass derivedInstance = BaseClass.Create<DerivedClass>();
Reflection
abstract class BaseClass
{
public static BaseClass Create(Type derivedType)
{
// Cast will throw at runtime if the created class
// doesn't derive from BaseClass.
return (BaseClass)Activator.CreateInstance(derivedType);
}
}
Where the usage would be (split over two lines for readability):
DerivedClass derivedClass
= (DerivedClass)BaseClass.Create(typeof(DerivedClass));
You want to create a new instance of derived from inside another instance of derived, using a static factory method on the abstract base class? if so, I wonder Why... But ...
public abstract class MyBase
{
public static T GetNewDerived<T>() where T : MyBase, new()
{
return new T();
}
}
public class DerivedA : MyBase
{
public static DerivedA GetNewDerived()
{
return GetNewDerived<DerivedA>();
}
}
public class DerivedB : MyBase
{
public static DerivedB GetNewDerived()
{
return GetNewDerived<DerivedB>();
}
}
Is this what you want ?
Sounds like you need to make the Create() method abstract. And once you do that you might as well rename it and make it the constructor as well. Then you can have a different Init() method that you call after the object is constructed if you need to, and normal polymorphism effects will handle things.
You can't do it without outside information; either the type of the derived class, an instance of it, or the fully-qualified name of the derived class. Any of these are equivalent to what you're already doing; there isn't a better solution I'm aware of. The very nature of static methods precludes anything more elegant.
I'm not sure what your design goals are but from what you asked it sounds like it might end up with alot of code smell. I think you should really look into the Inversion of Control(IoC) / Dependency Injection (DI) design patterns that are implemented in numerous frameworks such as Microsoft Unity, Castle Windsor, StructureMap, Ninject, Spring.Net and so forth.
I think if you look at using an IoC container it will solve your problem in a much cleaner and loosely coupled way.

Categories

Resources