I want to write a static utility class which only has a set of properties, which expose functionality to the user
For example I could call:
Utils.String.GetHexString("Hello World");
or
Utils.Stream.CopyBytes(instream, outstream);
The closest thing I could liken this to is System.Text.Encoding where there are properties like UTF8, ASCII etc, so yo can call things like:
Encoding.UTF8.GetBytes("Hello World");
or
Encoding.ASCII.GetBytes("Hello World");
The problem is that in Encoding, this calls the equivalent objects (UTF8Encoder, ASCIIEncoder) which are publicly available to the user. What I want is to expose the objects ONLY via Utils, without visibilty of the objects that relate to the properties, for example
I could call:
Utils.Stream.CopyStream(instream, outstream);
but I could not call:
StreamUtils.CopyStream(instr, outstr) //This class is only accessible via the Utils class!
Is this possible, and if it is, is it going to be good or bad practice to do so?
Here's an idea:
public interface IStreamUtil
{
void CopyStream(Stream int, Stream out);
}
internal class StreamUtil : IStreamUtil
{
// Implementation
}
public static class Util
{
private static IStreamUtil stream = new StreamUtil();
public static IStreamUtil Stream
{
get { return stream; }
}
}
To me, however, this is somewhat of a strange practice. Personally I prefer extension methods for utility functionality:
inStream.CopyStreamTo(outStream);
myString.GetHexString();
which can also be considered bad, especially taking into account extension method discovery and resolution algorithms. Good ol' StreamUtil.Copy() is just fine for most cases.
It is not possible to prevent any user from creating a variable of your StreamUtils type and e.g. assigning the value retrieved from your Utils.Stream property.
However, there are two solutions:
You can prevent users from creating instances of your StreamUtils class themselves by making the constructor internal. Like that, only your Utils class (to which you can grant internal access, be it by placing it in the same assembly or by using the InternalsVisibleTo attribute) can instantiate your StreamUtils class, while users of your library can only use the functions of your instance, but cannot create their own instance.
Another approach is using public nested static classes. Within your Utils class, you could declare a nested public static class Stream that offers the methods you need as static methods. Like this, users could not instantiate their own Stream instance (as it's static), and at least in C#, you would even force users to always write Utils.Stream to access your methods, if that is what you really want. Note, however, that this approach does not seem as clean as the first one and will cause breaking changes (at least on the binary level), should you ever decide to exchange the static classes with property getters or anything else.
What you want is possible, but you shouldn't see Utils as a class itself, but as a namespace that contains some static utility classes:
namespace Utils
{
public static class String
{
public static string GetHexString(string input)
{
...
}
}
public static class Stream
{
public static void CopyBytes(System.IO.Stream instream, System.IO.Stream outstream)
{
...
}
}
}
Whether this is a recommended practice or not, is a completely different issue. The problem with too many static utility classes, is that you can't have loose coupling by using dependency injection. This can make it harder to write good unit tests.
Looking at what you are trying to achieve, I suggest, try and develop extention methods.
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.
Read more on the hyperlink provided here.
Ok, basically it's no possible (in C# at least) to achieve exactly what I want. The class must be visible for the functionality to be visible through the Util class.
My solution was to turn the classes (e.g. StreamUtils, StringUtils) into singletons. They cannot be constructed because their constructors are internal. their methods are public but can never be seen because the object cannot be instantiated outside of my assembly. The Utils class exposes the functionality to the user via the singleton instance.
Consider the following:
class StreamUtils
{
static StreamUtils instance;
internal static StreamUtils Instance
{
get
{
if(instance == null)
{
instance = new StreamUtils();
}
return instance;
}
}
internal StreamUtils()
{
}
public void CopyStream(Stream input, Stream output)
{
}
}
static class Utils
{
public StreamUtils Stream
{
get
{
return StreamUtils.Instance;
}
}
}
Related
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?
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
}
}
We've just had a discussion with college about is the following style acceptable for oop or not.
We've a class, which has one public function, and requires a reader in the constructor:
public class Converter
{
private readonly IReader _reader;
public Converter(IReader reader)
{
_reader = reader;
}
public byte[] Convert(...params...)
{
return something;
}
}
We have Reader1 and Reader2 which both implement an IReader.
I want to setup two managers: Converter1 and Converter2, providing the same public Convert() function, but Converter1 will be using Reader1, and Converter2 will use Reader2.
For me the simplest solution is to inherit from Converter and initialize it with proper reader:
public class Converter1 : Converter
{
public Converter1():base(new Reader1())
{}
}
public class Converter2 : Converter
{
public Converter2():base(new Reader2())
{}
}
My college says, that Converter1 and Converter2 are Managers, and inheritance should not be used for managers, instead we should apply a composition here. But from my perspective composition will only result in additional code in specific converters classes.
So, could you please advice, whether it is ok to use inheritance when implementing managers or not?
Thanks
Why are you inheriting at all??
Based on the sample you have provided, you are not doing anything additional to the base class other than ensuring that Converter1/Converter2 enforces a specific type of reader.
It seems to me that your collegue is right. What you should be doing is implementing a Factory Method, that will create and populate the correctly configured Converter for you.
i.e.
public static class ConverterFactory {
public static CreateConverter1() {
return new Converter(new Reader1());
}
public static CreateConverter2() {
return new Converter(new Reader2());
}
}
...
Converter x = ConverterFactory.CreateConverter1();
To my mind, this is an abuse of inheritance. You aren't specializing the behaviour of the converter - you're only specializing the construction.
In particular, you could easily have a static class with static methods to perform this construction:
public static class Converters
{
public static Converter CreateConverter1()
{
return new Converter(new Reader1());
}
public static Converter CreateConverter2()
{
return new Converter(new Reader2());
}
}
These could even be static methods within the normal Converter class, of course.
The fact that this loses no functionality suggests to me that inheritance was a mistake.
Then again, I'm regularly suspicious of inheritance. Designing inheritance properly means working out the extension points, documenting how they should behave - which is a balancing act between giving callers enough information to predict consistent behaviour, and giving implementors enough wiggle room to vary the behaviour in useful ways. Here you're not doing any of this - you're just changing what reader is passed to the constructor.
Either use inheritance (like you proposed), or just use one Converter class which will work with the polymorphic IReader.
When should I prefer either a static or a normal class? Or: what is the difference between them?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace staticmethodlar
{
class Program
{
static void Main(string[] args)
{
SinifA.method1();
}
}
static class SinifA
{
public static void method1()
{
Console.WriteLine("Deneme1");
}
}
public static class SinifB
{
public static void method2()
{
Console.WriteLine("Deneme2");
}
}
public class sinifC
{
public void method3()
{
Console.WriteLine("Deneme3");
}
}
public class sinifD : sinifC
{
void method4()
{
Console.WriteLine("Deneme4");
}
sinifC sinifc = new sinifC(); // I need to use it :)
}
}
Static classes contain static objects that can't be instantiated multiple times. Usually what I use static classes for are to house static methods that provide calculations, general processing patterns, string output formats, etc. Static classes are light weight and don't need instantiation.
For instance System.IO.File is a static class with static a method Exists(). You don't create a File object to call it. You invoke it like this
System.IO.File.Exists(filePath)
Rather than doing this
System.IO.File myFile = new System.IO.File(filePath);
if(myFile.Exists())
{ /* do work */ }
If you require several objects in software, then you use dynamic classes. For instance if you have an inventory system you may have several Product objects and in that case you would use a dynamic class such as this
public class Product
{
public int ProductID { get; private set; }
public string ProductName { get; private set; }
public int Qty { get; set; }
public Product( int productID, string productName, int total )
{
this.ProductID = productID;
this.ProductName = productName;
this.Qty = total;
}
}
static classes cannot be instantiated or inherited.
static classes are marked as sealed and abstract by compiler in the output MSIL.
all members of static classes must be static as well.
only static classes can host extension methods.
static classes cannot be used as generic type arguments.
You can create instances of "normal" classes via the class constructor.
var normal = new Normal();
You cannot create instances of static classes. They can only have static methods.
Also worth noting is that you must declare extension methods in static classes.
From the MSDN documentation on static classes:
A class can be declared static, indicating that it contains only static members. It is not possible to create instances of a static class using the new keyword. Static classes are loaded automatically by the .NET Framework common language runtime (CLR) when the program or namespace containing the class is loaded.
In simple terms:
A static class cannot be instantiated using the new keyword.
All methods in a static class must be static and can be called directly without instantiation.
A "normal" class MUST be instantiated however any static methods in a "normal" class can be called without instantiation.
Non static methods in a "normal" class cannot be called without first instantiating the containing class.
Static members can be called without using an instance of the class. For example, a static Math class with an Area method call be called by Math.Area without instantiating the Math class first.
A normal class is one which you can instantiate and can use with objects.
A static class is one which can not be instansiated and can't be extended.
That means a static class is sealed and abstract by default, you may look at the
MSIL of a static class compiler puts sealed and abstract in front of a static class.
So, because a static class can't be instantiated, you can't have instance methods defined
on static classes, so all methods must be static and public ofcourse as you would want to
use them.
A static class is singleton by default.
Static classes are used for defining extension methods because you don't want to
instansiate them.
Static classes are like global provider of unique services.
I hope that make sense to you and will help you to understand the static classes.
It might help to think of "static" and "instance" in terms of memory addressing.
An object that is static exists in one and only one location in memory; you can't create instances of it because by definition it has been stated that it will be found in one particular location. It is "static" and unchanging. The creation of the object is implicit rather than explicit.
var result = Math.Pow(3, 3); // static - Math class can't be instanced
An object that isn't static can be instanced one or more times; you're saying, "Create for me an object of this type" and the object is given a memory address. You can create multiple instances that all exist in different memory addresses. The creation of the object is explicit using the new keyword.
var Ted = new Employee(); // instance - creates a new object at a new address
This is where people get into trouble in ASP .NET web programming; static classes are created once per Application Domain and their constructors are therefore only called once.
A static class is one that cannot be instantiated. Therefore, it cannot be used as a 'template" for multiple instances of some object that conforms to the class definition as a normal class can. In a normal class, the data members defined are created for each "instance" of the class, and each "instance" has it's own set of these data members, so these instances represent individual "entities" or complex in-memory data structures for some object (which you coded the class to represent).
When you define (code) a static class, all of it's data fields must also be static, meaning that they cannot be instantiated once for each instance of the class, (you can't create instances of a static class ). Static classes are useful only when you just need a container to hold methods that do not depend on the state of some object or data structure being managed by the application (like an add function, or a string formatter, etc.)
I am currently designing a class library that will provide data to a web application graph rendering engine in C#. I am currently defining the interfaces of this library.
I have a IGraphData interface which I would like to cache using a service that accesses the cache, this is called IGraphDataCacheService and has set and get methods to add and retrieve IGraphData objects to and from the cache. the cache service will be a singleton.
I am confused about the correct way to implement this, so that there is only one cache service that can get and set generic IgraphData objects.
I came up with this:
interface IGraphDataCacheService {
IGraphData<object> Get(string identifier);
void Set(IGraphData<object> graphData);}
or this:
T Get<T, P>(string identifier) where T : IGraphData<P>;
void Set<T,P>(T graphData) where T : IGraphData<P>;
Can any one offer any advice help?
Thanks
Why don't you just make the interface generic instead?
interface ICacheService<T> {
T Get(string identifier);
void Set(T graphData);
}
if you wanted, you could type-constrain T to be of type IGraphData, or you could write it as:
interface IGraphDataCacheService<T> {
IGraphData<T> Get(string identifier);
void Set(IGraphData<T> graphData);
}
A few points:
I'd probably rename the interface methods to be more emblematic of a caching service. For example, Fetch and Store instead of Get and Set, which makes it sound like you're getting or setting the provider rather than the data to be cached.
Ensuring that there is only one cache is an implementation detail, not an interface one.
To implement a singleton, try something like:
public class SingletonCacheService : IGraphDataCacheService {
private static Singleton instance;
private Singleton() {}
// snip implementation of IGraphDataCacheService methods ...
public static Singleton Instance {
get {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
}
Note that this simple version isn't threadsafe.
Both alternatives seem plausible at a glance; my hunch is that you need to write some 'typical' client code to decide. e.g. Does the typical client 'know' the type of data associated with the identifier it's looking up? Good API design requires identifying the main use scenarios and using that to inform the design.
If I understand your question correctly you are wanting to treat the generic types like they are the same, but in current .NET implementation you can't do this.
IGraphData<string> can't be passed as a IGraphData<object> they are actually different types even though string is an object, the generic types are not related and can't be cast or passed like they are the same.
If you control the IGraphData interface you can create a IGraphData interface and derive IGraphData from it and use IGraphData to access the cache. It just depends on how you are using it and what you have the control over.
You can do what you want in C# 4.0. There is an article about it here
You can't ensure there's only a single instance implementing an interface. However, you can make a class (e.g. GraphDataCacheServiceImpl) implementing the interface a singleton by sealing it and providing only a getter property, with the object created as a static variable from a private constructor. See the below. As far as generics, it's not exactly clear what you're seeking to accomplish. But I would guess the below is close to what you want.
interface IGraphDataCacheService<T> {
IGraphData<T> Get(string identifier);
void Set(IGraphData<T> graphData);
}
public sealed class GraphDataCacheServiceImpl<T> : IGraphDataCacheService<T>
{
private GraphDataCacheServiceImpl()
{
// ..
}
static GraphDataCacheServiceImpl()
{
Instance = new GraphDataCacheServiceImpl<T>();
}
public IGraphData<T> Get(string id)
{
return new GraphDataImpl<T>();
}
public void Set(IGraphData<T> graphData)
{
}
public static GraphDataCacheServiceImpl<T> Instance {get; private set;}
}