Calling a common method across multiple static classes? - c#

A Quick Note
The code in this post is built on top of a in-house built DirectX-11 engine which means it follows the strict pattern of:
Initialize
while (Running) {
Update
Render
}
However, do not let this deter you as the problem is not related to the DirectX code but instead static classes and methods.
Overview
I have a class called RenderObject which contains a method called Initialize. This method is responsible for building the object's mesh, assigning textures, shaders, and more.
public class RenderObject {
public virtual void Initialize() { }
}
I also have a few static classes that hold reusable assets such as common textures, shaders, models, and meshes. This way I don't have to reload them later. All of these static classes also contain a method called Initialize which is responsible for creating these reusable assets. For this question I will limit this to just the Textures class.
public static class Textures {
public static Texture2D Dirt { get; private set; }
public static Texture2D Grass { get; private set; }
public static void Initialize() {
Dirt = new Texture2D(...);
Grass = new Texture2D(...);
}
}
Finally, I have a class called LoadingSystem which is responsible for loading reusable assets and initializing objects. I initialize this class inside of the Initialize method of my engine, and then call the class' Update method in the Update method of the engine respectively. The LoadingSystem's Update method is responsible for loading and initializing objects using a Queue which is useful for supplying smooth visual feedback.
public class LoadingSystem {
public bool Loading { get; private set; } = true;
private Queue<RenderObject> objectsToRender;
public void AddForLoad(RenderObject obj) => objectsToRender.Enqueue(obj);
public void Update() {
if (objectsToRender.Count > 0) {
RenderObject obj = objectsToLoad.Dequeue();
obj.Initialize();
} else Loading = false;
}
}
The Problem
I would like to call the method Initialize on these static classes with the same process used for the RenderObject queue. Currently I'm forced to do:
CurrentMessage = "Loading Textures";
Render();
Present();
Textures.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
CurrentMessage = "Loading Shaders";
Render();
Present();
Shaders.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
CurrentMessage = "Loading Models";
Render();
Present();
Models.Initialize();
Progress = ++objectsLoaded / objectsToLoad;
I've slimmed it down to a method that handles the repetitive setting of the message, and calls to Render and Present but this is still tedious and it should go through the Update method once per object to remain consistent with the rest of the code.
My Thoughts
I understand that a static class cannot inherit from a class or implement an interface so I am wondering if there is a way to provide a static class and call its Initialize method in a similar manner; even if this means creating a separate method to accomplish it.
I have currently considered two options:
Load static classes individually.
Convert static classes to instance classes and call them with the queue.
The problem with the first option is that I have 12 static classes and would have to update progress and feedback messages, raise events, and re-render the scene for each one.
The problem with the second option is that these static classes only contain static properties and thus by definition should be static as there is no need to ever inherit from them or create an instance of them.
The Question
Is there a way to call a common method across multiple static classes?
Perhaps a way to call the method if it exists with generic types like object or T?
Perhaps the dynamic type may work (though you can't create an instance of static classes)?

I have currently considered two options:
Load static classes individually.
Convert static classes to instance classes and call them with the queue.
A third compromise approach relates to your second idea above, but uses a design pattern known as the Singleton Pattern. Like static classes, there can only be one of them in your process and everyone gets that same thing, however unlike static classes, Singletons can implement interfaces or even descend from other classes.
For this example, I will use the interface approach.
public interface IInitializable
{
void Initialize();
}
All the interface does is to enforce that its implementer has an Initialize method.
My next step is to create a Singleton class. There are a couple of rules to implement the Singleton pattern. Your class must be sealed. Its constructor must be private. It must have a static method or property to return the single instance. That method/property must be threadsafe.
I have used Lazy to do the heavy lifting for me
public sealed class Foo : IInitializable
{
public void Initialize()
{
// Initialize my foo
}
private Foo()
{
}
private static Lazy<Foo> fooLazy = new Lazy<Foo>(() => new Foo());
public static Foo Instance => fooLazy.Value;
}
There are some minor differences to what you were doing with static classes. If Foo was a static class, you would call Foo.Initialize(); As it is Singleton, you would call Foo.Instance.Initialize();
Any other methods or properties would most likely be non-static.
Pulling it all together, you could write code like this. Your queue does not need to know about the classes it holds. You don't actually care. You only want to know that it has the Initialize() method
public class YourClass
{
private Queue<IInitializable> objectsToLoad = new Queue<IInitializable>();
public void Enqueue(IInitializable obj)
{
this.objectsToLoad.Enqueue(obj);
}
public void LoadOrUpdate()
{
// Update Method
if (objectsToLoad.Count > 0)
{
IInitializable obj = objectsToLoad.Dequeue();
obj.Initialize();
}
else
{
// Loading complete.
}
}
}
This class could then be used like this
YourClass yourClass = new YourClass();
yourClass.Enqueue(Foo.Instance);
yourClass.LoadOrUpdate();

Though I hope there is a much better and more detailed answer than this; I've come up with a basic solution. I created a separate Queue<Type> where I add the static classes. I then call their Initialize method with the following:
Type t = typesToInit.Dequeue();
t.GetMethod("Initialize").Invoke(null, new object[] { 0 });
This works well and is rather clean, but I can't help but wonder if there is a better way to do this?

Related

Using Static methods in the helper class vs non-static

I have a helper class that takes some object, processes it and returns back some instance of the other class or even the List of the objects.
What would be the best way: to make this helper method static or non-static?
The thing is that my app can create lots of the Car objects and I was thinking whether it could have a negative effect when each of them use the static helper?
Probably this is something that can be solved without deciding the helper object's life-cycle where you require it.
You should try to leverage dependency injection approach:
public class X
{
public X(IHelper helper)
{
Helper = helper;
}
private IHelper Helper { get; }
public void DoStuff()
{
var result = Helper.DoOtherStuff(input);
}
}
That is, X don't know whether Helper is always the same instance or if it's a transient object. This makes the code cleaner and more test-friendly, because you can mock the helper with a fake IHelper implementation to be sure that you're just testing X.
Most helper or utility classes use static methods. You should only use non-static methods if you want to create multiple instances of your helper class, but since you just need a simple input -> function -> output, I would make the methods static.
Use static class with static methods, No instance, no derivation and only static methods in the class.
public static class HelperClass
{
public static void HelperMethod()
{
// do something
}
}

When should I use inheritance over utility classes?

I am working on a project that uses Canvas objects. I would like to add a few functionalities to manipulate them.
Until now, I was adding them in a CanvasUtils class but now I realize that I could actually create a CustomCanvas class that would inherit from Canvas and implement the new functionalities.
I can feel the second way is more intuitive but I am not sure whether it is the best option or not.
For example, if I keep adding new methods to a CustomCanvas class it is going to become huge at some point whereas I can easily break a utils class into several ones.
Also a Utils class sounds more independent and extendable to me. For example, if I wanted to extend some of the functionalities to Panel objects (Canvas inherits from Panel), I think it would be easier to do it with a Utils class as you just have to change the Canvas references to Panel.
My questions are:
what are the advantages and flaws of each method and
when should I use one over another?
If you are adding new functionality, then you should extend the class. You'll be able to add your own state, as well as methods to interact with them. However, you won't be able to add this functionality to existing objects.
If you are simply writing shortcuts that use existing functionality, then you can use Extension Methods to add functions without needing to extend the class. For example...
public static class PanelExtensions
{
public static void DoSomething(this Panel panel)
{
panel.SomePanelMethod();
panel.SomeOtherPanelMethod();
}
}
And then to use this...
Panel myPanel = new Panel();
myPanel.DoSomething();
The advantage of this approach is that the methods are available to existing panels, and they will be inherited too (so your Canvas objects will receive these methods too).
Note than in order to use extension methods, you need to have a using statement at the top of your file referencing the namespace in which they are defined.
It depends on what you are trying to achieve and what do you need to implement new functionality:
If you have stateless methods that do not need any additional information associated with object, then you can either continue to use Util methods or turn them into Extension methods that will give you both the inheritance-like feel of use and loose coupling of the Util class:
public static class CanvasExtensions
{
public static void TransformElements(this Canvas canvas,
Action<CanvasElement> transform)
{
...
foreach(var elem in canvas.Children)
{
transform(elem);
}
...
}
}
If you need to associate some piece of info with the object you operate on, then:
you can either inherit the class if the object's behaviour shall be deeply affected by additional functionality (like when other standard methods can negate new functionality) to allow base function overriding:
public class DeeplyAffectedCanvas : Canvas
{
private IDictionary<CanvasElement, Action> m_dictionary;
public void SpecialTransform(CanvasElement elem, Action transform) { }
public override void Resize()
{
// Resize, for example, have to take into account
// the special operation
}
}
or create a wrapper, that exposes the original object (Panel) when the additional behaviour doesn't affect the wrapped object much:
public class Wrapper<T>
{
public Wrapper(T wrapped)
{
this.Wrapped = wrapped;
}
public T Wrapped { get; private set; }
public implicit operator T (Wrapper<T> wrapper)
{
return wrapper.Wrapped;
}
}
public class WrappedCanvas : Wrapper<Canvas>
{
private Object data;
public void SafeTransform(...);
}

C#: Giving access to private members without 3-fold code duplication

I have a class
public class Foo{
public Foo{...}
private void someFunction(){...}
...
private Acessor{
new Acessor
}
}
with some private functionality (someFunction). However, sometimes, I want to allow another class to call Foo.SomeFunction, so I have an inner class access Foo and pass out that:
public class Foo{
public Foo{...}
private void someFunction(){...}
...
public Acessor{
Foo _myFoo;
new Acessor(Foo foo){_myFoo = foo;}
public void someFunction(){
_myFoo.someFunction();
}
}
}
With this code, if I want a Foo to give someone else pemission to call someFunction, Foo can pass out a new Foo.Accessor(this).
Unfortunately, this code allows anyone to create a Foo.Accessor initiated with a Foo, and they can access someFunction! We don't want that. However, if we make Foo.Accessor private, then we can't pass it out of Foo.
My solution right now is to make Acessor a private class and let it implement a public interface IFooAccessor; then, I pass out the Foo.Accessor as an IFooAccessor. This works, but it means that I have to declaration every method that Foo.Accessor uses an extra time in IFooAccessor. Therefore, if I want to refactor the signature of this method (for example, by having someFunction take a parameter), I would need to introduce changes in three places. I've had to do this several times, and it is starting to really bother me. Is there a better way?
If someFunction has to be accessible for classes in the same assembly, use internal instead of private modifier.
http://msdn.microsoft.com/en-us/library/7c5ka91b(v=vs.71).aspx
If it has to be accessible for classes which are not in the same assemble then, it should be public. But, if it will be used by just a few classes in other assemblies, you probably should think better how you are organizing you code.
It's difficult to answer this question, since it's not clear (to me at least) what exactly you want to achieve. (You write make it difficult for someone to inadverdantly use this code in a comment).
Maybe, if the method is to be used in a special context only, then explicitly implementing an interface might be what you want:
public interface ISomeContract {
void someFunction();
}
public class Foo : ISomeContract {
public Foo() {...}
void ISomeContract.someFunction() {...}
}
This would mean, that a client of that class would have to cast it to ISomeContract to call someFunction():
var foo = new Foo();
var x = foo as ISomeContract;
x.someFunction();
I had a similar problem. A class that was simple, elegant and easy to understand, except for one ugly method that had to be called in one layer, that was not supposed to be called further down the food chain. Especially not by the consumers of this class.
What I ended up doing was to create an extension on my base class in a separate namespace that the normal callers of my classes would not be using. As my method needed private access this was combined with explicit interface implementation shown by M4N.
namespace MyProject.Whatever
{
internal interface IHidden
{
void Manipulate();
}
internal class MyClass : IHidden
{
private string privateMember = "World!";
public void SayHello()
{
Console.WriteLine("Hello " + privateMember);
}
void IHidden.Manipulate()
{
privateMember = "Universe!";
}
}
}
namespace MyProject.Whatever.Manipulatable
{
static class MyClassExtension
{
public static void Manipulate(this MyClass instance)
{
((IHidden)instance).Manipulate();
}
}
}

Private class with Public method?

Here is a piece of code:
private class myClass
{
public static void Main()
{
}
}
'or'
private class myClass
{
public void method()
{
}
}
I know, first one will not work. And second one will.
But why first is not working? Is there any specific reason for it?
Actually looking for a solution in this perspective, thats why made it bold. Sorry
It would be meaningful in this scenario; you have a public class SomeClass, inside which you want to encapsulate some functionality that is only relevant to SomeClass. You could do this by declaring a private class (SomePrivateClass in my example) within SomeClass, as shown below.
public class SomeClass
{
private class SomePrivateClass
{
public void DoSomething()
{
}
}
// Only SomeClass has access to SomePrivateClass,
// and can access its public methods, properties etc
}
This holds true regardless of whether SomePrivateClass is static, or contains public static methods.
I would call this a nested class, and it is explored in another StackOverflow thread.
Richard Ev gave a use case of access inside a nested classes. Another use case for nested classes is private implementation of a public interface:
public class MySpecialCollection<T> : IEnumerable<T>
{
public IEnumerator<T> GetEnumerator()
{
return new MySpecialEnumerator(...);
}
private class MySpecialEnumerator : IEnumerator<T>
{
public bool MoveNext() { ... }
public T Current
{
get { return ...; }
}
// etc...
}
}
This allows one to provide a private (or protected or internal) implementation of a public interface or base class. The consumer need not know nor care about the concrete implementation. This can also be done without nested classes by having the MySpecialEnumerator class be internal, as you cannot have non-nested private classes.
The BCL uses non-public implementations extensively. For example, objects returned by LINQ operators are non-public classes that implement IEnumerable<T>.
This code is syntactically correct. But the big question is: is it useful, or at least usable in the context where you want to use it? Probably not, since the Main method must be in a public class.
Main() method is where application execution begin, so the reason you cannot compile your first class (with public static void Main()) is because you already have Main method somewhere else in your application. The compiler don't know where to begin execute your application.
Your application must have only one Main method to compile with default behavior otherwise you need to add /main option when you compile it.

Force singleton pattern in subclasses

I would like to force subclasses to implement the singleton pattern.
I originally thought of having an abstract static property in the parent class, but upon closer though, that didn't make sense (abstract requires and instance).
Next, I thought of having an interface with a static property, but that also doesn't make sense (interfaces also require an instance).
Is this something which is possible, or should I give up this train of thought and implement an abstract factory?
Please reconsider. You do NOT want to use singletons here. You are making some functionality available to users who derive from your class. That's fine. But you're also dictating one specific way in which it must always be used, and for absolutely no reason. That is not good.
It may make sense to only instantiate one object of this class the majority of the time, but in that case, simply just instantiate the object once. It's not like you're very likely to accidentally instantiate a dozen objects without noticing.
Moreover, how can you tell that having two instances will NEVER be useful? I can think of several cases even now.
Unit testing: You might want each test to instantiate this object, and tear it down again afterwards. And since most people have more than one unit test, you'll need to instantiate it more than once.
Or you might at some point decide to have multiple identical/similar levels in your game, which means creating multiple instances.
A singleton gives you two things:
A guarantee that no more than one instance of the object will ever be instantiated, and
Global access to that instance
If you don't need both these things, there are better alternatives.
You certainly don't need global access. (globals are bad, and usually a symptom of bad design, especially in mutable data such as your game state)
But you don't need a guarantee that no more than one instances will ever be instantiated either.
Is it the end of the world if I instantiate the object twice? Will the application crash? If so, you need that guarantee.
But in your case, nothing bad will happen. The person instantiating the object simply uses more memory than necessary. But he might have a reason.
Simply put in the class documentation that this is a very big and expensive class, and you shouldn't instantiate it more often than necessary. Problem solved. You don't remove flexibility that might turn out to be useful later on, you don't grant global access to data for no reason. Because you can control who can see the object, you don't need to drown it in locks that will become a bottleneck in multithreaded applications. You don't have hidden dependencies scattered throughout your code, making it harder to test and harder to reuse.
Try using an IOC container. Most good IOC containers enable the use of the singleton pattern without having to implement it yourself (ie: spring framework) - I like this better than forcing a static GetInstance() method.
Besides, it's not really possible in java, it would work in C++ with templates though.
Why? If someone wants to use multiple instances of a subclass of your class they might have a perfectly valid reason to.
If you want to do something that only should be done once for each class that subclasses your class (why, I have no idea, but you might have a reason to), use a Dictionary in the base class.
I would define a sealed class that gets its functionality from delegates passed to the constructor, something like this:
public sealed class Shape {
private readonly Func<int> areaFunction;
public Shape(Func<int> areaFunction) { this.areaFunction = areaFunction; }
public int Area { get { return areaFunction(); } }
}
This example does not make a lot of sense, it just illustrates a pattern.
Such a pattern cannot be used everywhere, but sometimes it helps.
Additionally, it can be extended to expose a finite number of static fields:
public sealed class Shape {
private readonly Func<int> areaFunction;
private Shape(Func<int> areaFunction) { this.areaFunction = areaFunction; }
public int Area { get { return areaFunction(); } }
public static readonly Shape Rectangle = new Shape(() => 2 * 3);
public static readonly Shape Circle = new Shape(() => Math.Pi * 3 * 3);
}
I think you will be better off with a factory pattern here to be honest. Or use an IoC tool like Brian Dilley recommends. In the c# world there are loads, here are the most popular : Castle/windsor, StructureMap, Unity, Ninject.
That aside, I thought it would be fun to have a go at actually solving your problem! Have a look at this:
//abstract, no one can create me
public abstract class Room
{
protected static List<Room> createdRooms = new List<Room>();
private static List<Type> createdTypes = new List<Type>();
//bass class ctor will throw an exception if the type is already created
protected Room(Type RoomCreated)
{
//confirm this type has not been created already
if (createdTypes.Exists(x => x == RoomCreated))
throw new Exception("Can't create another type of " + RoomCreated.Name);
createdTypes.Add(RoomCreated);
}
//returns a room if a room of its type is already created
protected static T GetAlreadyCreatedRoom<T>() where T : Room
{
return createdRooms.Find(x => x.GetType() == typeof (T)) as T;
}
}
public class WickedRoom : Room
{
//private ctor, no-one can create me, but me!
private WickedRoom()
: base(typeof(WickedRoom)) //forced to call down to the abstract ctor
{
}
public static WickedRoom GetWickedRoom()
{
WickedRoom result = GetAlreadyCreatedRoom<WickedRoom>();
if (result == null)
{
//create a room, and store
result = new WickedRoom();
createdRooms.Add(result);
}
return result;
}
}
public class NaughtyRoom :Room
{
//allows direct creation but forced to call down anyway
public NaughtyRoom() : base(typeof(NaughtyRoom))
{
}
}
internal class Program
{
private static void Main(string[] args)
{
//Can't do this as wont compile
//WickedRoom room = new WickedRoom();
//have to use the factory method:
WickedRoom room1 = WickedRoom.GetWickedRoom();
WickedRoom room2 = WickedRoom.GetWickedRoom();
//actually the same room
Debug.Assert(room1 == room2);
NaughtyRoom room3 = new NaughtyRoom(); //Allowed, just this once!
NaughtyRoom room4 = new NaughtyRoom(); //exception, can't create another
}
}
WickedRoom is a class that properly implements the system. Any client code will get hold of the singleton WickedRoom class. NaughtyRoom does not implement the system properly, but even this class can't be instantiated twice. A 2nd instantiation results in an exception.
Although this will not enforce the user to have a singleton subclass, you can enforce the user to create only one instance of the class (or its sub-classes) as below. This will throw error if a second instance of any subclass is created.
public abstract class SuperClass {
private static SuperClass superClassInst = null;
public SuperClass () {
if(superClassInst == null) {
superClassInst = this;
}
else {
throw new Error("You can only create one instance of this SuperClass or its sub-classes");
}
}
public final static SuperClass getInstance() {
return superClassInst;
}
public abstract int Method1();
public abstract void Method2();
}

Categories

Resources