WPF C#: Static classes, when to use them?
1 20 Jun 2018 22:03 by u/auto_turret
So, I've built a data logger device communicating via Modbus protocol. Works great, firmware is my field of somewhat expertise. I've been crash coursing C# for the past couple weeks, trying to get my head wrapped around object-oriented coding, in order to build myself an app to view the sensor data from my device as a continuous plotting chart. The device can broadcast sensor data from 8 different channels.
Only took me a weekend to get a demo up and running, but not utilizing any sort of OOP-like code, since I don't really know what the fuck I'm doing with OOP yet.. The code looked like a trad C garage-class code piece of crap.
I've been trying to follow the MVVM model, I have the different functional parts broken up: CaptureEngine.cs - has everything I need to extract the incoming sensor data. I simply pass it a baud rate and com port, run the connect function, and the engine updates the ChannelModel for 8 channels as the data logger sends it. We trigger an event to notify new data is available, so the ChannelModel is updated on every trigger.
ChartingEngine.cs - Uses the data from ChannelModel to plot a chart
ChannelModel.cs - Contains 8 channel labels (strings) and 8 channel present values (double). Contains an event to let the ChartEngine know new data is available, and to plot it. MeasureModel.cs - Simply a class with two properties, time and present value. This is the package I send the current channel data to the ChartEngine.
MainWindow.cs - Basically just initializes and starts the CaptureEngine and ChartEngine
ViewModel.cs - Contains properties of visible data, (channel_1_label_vm, channel_2_label_vm... etc). Also contains code for the visual elements such as buttons, textboxes, etc.
I'm wondering.. is making my ChannelModel a static class, so that all classes can see the channel data it contains, a good move? Because creating a non-static instance doesn't seem to work.. the other classes won't see it.
Now this all works just fine, but the whole static ChannelModel class seems like I'm misbehaving/not utilizing C# like I should be..
My question I'm hoping to get some insight into is, in what situations would you use a static class? Is it common for static classes to be used incorrectly/abused?
12 comments
2 u/grim89 20 Jun 2018 23:37
Static classes are generally considered an anti pattern and have few and very specific uses cases (don't remember them of the top of my head). In your example you don't need a static class so u shouldn't use it. All you need to do is pass the instance of ChannelModel to the classes that use it. So let say your ViewModel.cs need ChannelModel you do something liked this.
You should look into Dependency Injection and Inversion of Control since is pretty much a standard now.
Dependency Injection (DI) vs. Inversion of Control (IOC)
0 u/auto_turret [OP] 21 Jun 2018 00:25
Thanks for the reply. I'm drawing out my program for the umpteenth time, it is slowly starting to click I think..
I believe my trouble is, I keep reverting to thinking like I'm coding a microcontroller which keeps me running into roadblocks.
Referencing your code: I see what you did there, didn't realize I could pass along the whole instance and it's current state.
I believe now, if I put an event listener in that ViewModel constructor instead, and stick _channelModel = channelModel in a method that will call, it should listen for a newdata available event and update itself accordingly, so long as I've created a new ViewModel instance in my main program.
I'll give it a shot. Thanks man, that was super helpful. Going to check out the links you've provided.
0 u/roznak 22 Jun 2018 23:50
IoC tends to turn out into very messy code and hard to reverse engineer. If you did not create the code yourself or were part of it then you are toast.
In a perfect world where programs are perfect, analysis done right and developers never make mistakes, then IoC is good. But the hard reality is that when you inherit code that you started but others took over and they tell you fix the bugs.
On top of that IoC, actually explodes the amount of code that you need exponentially to do the exact same job.
The sad reality is that if jump on this IoC bandwagon, your brain gets trapped that this is the only possible solution and you lose the ability into train your brain into creativity. You become slave of the code, instead of the master.
0 u/auto_turret [OP] 23 Jun 2018 19:42
Exactly what I observe. Coming from firmware programming where sometimes your usable ram is measured in BYTES, I kept initially gravitating towards trying to make every bit and byte count. Well, it just don't work that way in Windows app coding..
I can see how it could be quite helpful in swapping modules down the road, and my small app so far seems it could be easily followed and understood without excessive commentary.
0 u/2308482093842 21 Jun 2018 10:27
Static classes can sometimes make sense, but often they are just a quick and dirty hack and they make your code harder to extend in the future.
Only if there's no way in hell that you could ever use a second instance of something, only then a static class makes sense.
But 99.9% of the time, you can actually Benefit from allowing more than one instance.
Often, beginners initially like static classes, because you don't have to pass the objects to all your other objects, which is tedious.
But there is a middle Ground:
Now you have your "static" instance that you don't have to pass around, but you can have multiple instances, since the class is not static.
0 u/auto_turret [OP] 21 Jun 2018 13:50
Cool man, I did use something exactly like that to access my Receive() in my CaptureEngine class from my RS232Functions class. Something to the effect of
and
to use it.. so far that's been working out for me.
0 u/poloport 25 Jun 2018 17:43
Thanks dude! I knew how static classes worked, but that work around is really useful!
0 u/roznak 23 Jun 2018 00:04
If you start with static classes first then you will end up having code that is not extendable and thread safe. Also you can always nail down a dynamic class as static like a singleton.
I tend to initialize static classes at my Main() first. This way I have a predictable place where the code gets initialized.
0 u/auto_turret [OP] 23 Jun 2018 10:02
I've re-written the darn thing again, but this time using the dependency inversion principle. NOW things make more sense.. high level modules don't depend on lower level modules, but rather abstractions that don't rely on details.
Works for everything BUT the serialport functions. It appears it must be static or my port won't stay open.
0 u/auto_turret [OP] 24 Jun 2018 14:22
Scratch the last comment, got rid of the static from SerialPort too. I think I've pretty much got this concept down, now. Been banging my head for a month, then finally came to you guys for advice. Turns out that's exactly what I needed!
0 u/roznak 24 Jun 2018 20:17
Nice to hear.
0 u/whambamthankyouham 25 Jun 2018 23:34
Static class -> When you only want one of something.
If you create a level in a game as a class, you (typically) only want one instance of that level.