Private Static Members inside a Static Class... Good idea? - c#

I created a static class with a private static member inside of it. That private static member is accessible to all of my static class methods.
This happened while I wasn't really paying attention, but then I realized what I had done, and that - interestingly enough - it seems to be working fine in my application. Nonetheless, it seemed like a silly thing to do (coming from C++), so I have been searching around trying to find more info on whether this is really supposed to be possible and/or if it is considered good or bad practice, but I haven't really been able to find anything at all about creating private static members inside a static class in C#.
It almost seems like static methods inside my static class have an implicit "this" variable (since I'm also able to call other methods without fully qualifying them with the class name), which feels a be peculiar to me.
I was hoping some of you might have some thoughts about whether this is a good idea or not, and why C# makes this possible at all.
The class:
public static class ControlHighlighter
{
private static Panel highlightPanel = null;
public static void Highlight(Control control = null, int thickness = 1)
{
RemoveHighlight();
if (control != null)
{
if (control.Parent != null)
{
highlightPanel = new Panel();
control.Parent.Controls.Add(highlightPanel);
highlightPanel.Location = new Point(control.Location.X - thickness,
control.Location.Y - thickness);
highlightPanel.Size = new Size(control.Size.Width + (2 * thickness),
control.Size.Height + (2 * thickness));
highlightPanel.SendToBack();
highlightPanel.BackColor = SystemColors.Highlight;
}
}
}
public static void RemoveHighlight()
{
if (highlightPanel != null)
{
highlightPanel.Dispose();
highlightPanel = null;
}
}
}

In general, there's nothing wrong with having private static members in static classes (or even in non-static classes). They do pose some potential problems, though: when your application is multithreaded, these static members are shared across all threads so you have to apply locking around them.
Since you never know if you need to make your application multithreaded, it's best to keep the number of static variables to a minimum - all static variables shared between threads must be protected through locks or other synchronization primitives. It's far easier to do this kind of work ahead of time than patching problems later on.
However, in your specific example, you're putting a UI control in a static variable - this is something I'd definitely advise against. UI controls live on the UI thread and must be properly invoked when called from a different thread. Threading issues aside, putting a control in a static variable is a recipe for trouble - the static variable requires careful bookeeping to clean up - if the form hosting the control goes away, the static reference will still keep it in memory (because the control cannot go away). This can lead to all kinds of hard-to-find problems.
If you're not familiar with static in C#, I recommend reading MSDN for more detail.

It almost seems like static methods inside my static class have an implicit "this" variable
Correct. A static class cannot be instantiated. Because there is no instance variable, you access the members of a static class by using the class name itself. When you're within the scope of the static class, accessing the static members within does not require prefixing it with an instance variable (this).
I was hoping some of you might have some thoughts about whether this is a good idea or not
Really .. the only issue is in a multi-threaded environment. Since this class and its data will be shared across threads (a single instance ..) then you'll need to synchronize around its access. In general, a static class should avoid maintaining state for this very reason.

Related

Need some clarification about the static constructor VS static field initializer story in C#

A couple of days ago I asked myself about the difference, if any, between initializing static fields via
the static constructor and doing so by using a static field initializer (inline initialization of a static field at the point of declaration).
After reading plenty of stackoverflow questions on the subject and the famous Jon Skeet's article on the beforefieldinit flag I've now a much better understanding of the difference between the two initialization strategies.
There is one point that I'm not sure about, mostly because I wasn't able to find any official documentation about it.
The static construcutor is guaranteed to be executed only once and I think this holds true even in multi threading scenarios (when different threads create instances of the class and / or use static members of the class. In any case, the static constructor runs once and only once).
Is this true even for the inline initialization of the static fields ? Is the inline initialization of a static field guaranteed to be executed once even in multi threaded scenarios ?
Another point I'm still missing is what are the practical consequences of this difference in the initialization of the static fields of a class. Put another way, I would like to understand when the correctness of a piece of code can be affected by the choice of initializing a static fied inline at the point of declaration (instead of using the static constructor).
Most of the time (this depends mostly on the type of code that I usually work on, namely web applications) I use static readonly fields in service classes to store things that are used by the service I'm writing to perform computations or taking decisions. I decide to put these things inside static fields because they need to be the same for all the possible instances of the class I'm writing, they are actually invariants that don't belong to a particular instance, but instead they belong to the algorithm itself.
This is an example:
public class SomeInterestingService
{
private static readonly int ConstantNumber = 13;
private static readonly string[] Names = new[] { "bob", "alice" };
private readonly INumberGenerator numberGenerator;
public SomeInterestingService(INumberGenerator numberGenerator)
{
this.numberGenerator = numberGenerator ?? throw new ArgumenNullException(nameof(numberGenerator));
}
public int ComputeMagicNumber()
{
int answer = this.numberGenerator.GetNumber();
foreach(var name in names)
{
answer += name.Length;
}
answer += ConstantNumber;
return answer;
}
}
In code like this, is there any practical difference in chosing static constructor initialization or inline initialization of the static fields ConstantNumber and Names, apart from the difference in performance (inline initialization is more performant due to runtime optimizations that are not possible when using the static constructor) ?
Can the correctness of the code above be affected by the coiche in any strange corner case ? (I think not)
Original question:
In code like this, is there any practical difference in chosing static
constructor initialization or inline initialization of the static
fields ConstantNumber and Names, apart from the difference in
performance (inline initialization is more performant due to runtime
optimizations that are not possible when using the static constructor)
?
The answer is no. Either those properties are set upon each construction of the class (instance properties) or set upon the first call to any of the members or methods to the class (static properties).
What #Henk Holterman is saying that because the array of names is a reference type you could theoretically change any of the values in the array. Like:
Names[0] = "Henk Holterman";
Even though the property is readonly. Meaning, you can't assign a new instance of array to that property. The values in the array are not readonly. And could be manipulated if public or by calling a method of that class.

Why is it not possible to set a Public Var?

I am trying to set the following public var:
var collection = new Dictionary<string, Statistics>();
I want to be able to use the same collection all through my application and i therefore want to create it right at the top when the applications starts.
How would i do this?
There is no concept of a global variable in C#. You always have to declare variable inside some class/scope.
What you can do, is to make it accessible via public modifier, like a property (say).
Just an idea:
public class Shared
{
public Dictionary<string, Statistics> CollectionDic {get;set;}
public Shared() {
CollectionDic = new Dictionary<string, Statistics>();
}
}
After you can access it like:
var shared = new Shared();
shared.CollectionDic.Add(..)
...
You have to workout by yourself, what fits your exact needs.
You can create it as a public static field or property in public class (optionally also static):
public class Variables
{
public static Dictionary<string, Statistics> collection = new Dictionary<string, Statistics>();
}
Then access it in code:
Variables.collection.Add(...);
Note that it is not thread-safe approach. So if you intend to use static dictionary in multithreading app, it's better to either have static methods, wraping the dictionary in thread-safe way (as Jon Skeet mentioned) or use thread-safe collections, for exapmle ConcurrentDictionary.
The error you are getting is:
The contextual keyword 'var' may only appear within a local variable
declaration
I believe you are trying to define your collection as:
public partial class Form1 : Form
{
var collection = new Dictionary<string, Statistics>();
You can't use var keyword at this level,
I want all of my Form1.cs to access it, not different .cs files
You may define it like:
Dictionary<string, Statistics> collection = new Dictionary<string, Statistics>();
It will be available to all the methods inside the Form1 class
EDIT
The comments of the OP showed, that the requirement is only to be able to access the variable through the one .cs code. Please disregard the following, and please vote delete if you think that this answer is not a valuable addition to the question for future visitors of this topic. Or vote up, if you think it has enough added value to stay.
What I meant for the original question, regarding I want to be able to use the same collection all through my application
In an object oriented environment, if this is a requirement that can not be surpassed by refactoring/restructuring the application, you should definitely use the Singleton design pattern
A singleton is a pattern, which guarantees that only one instance of the given class exists (per application contex/virtual machine, of course), and that that instance can be accessed from everywhere in the context of the same application.
That is:
create a class (e.g. by name MyDictionary)
implement the necessary functions you want from it (you want this to be independent of the underlying implementation)
make it a singleton by following the article
decide if you need lazy loading
I'd recommend to always use thread safe implementation when dealing with singletons to avoid unwanted consequences.
access from whenever you like
Example: (from the C#Indepth link, second version, having simple thread safety, take note who the author of the article is!)
public sealed class Singleton
{
private static Singleton instance = null;
private static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
BEWARE always take thread safety into count!
As I got a response from #JonSkeet (yikes!), I think I have to explain the rationale behind my answer:
Pros:
It is better than having some non-standard way of doing so
It is better than having to pass it around to every bit of code that exists
Cons:
It is absolutely not recommended, if this requirement can be circumvented by any means
having a singleton map around is a serious bad smell: keeps references throughout the life of the application, leading to massive leaks more often than not
multithreaded behaviour is something that is not trivial, and especially difficult to go after if something misbehaves only very rarely (hidden race conditions, and whatever else lurking under the bed of a programmer during nightmares)
Also recommended reading:
Singleton pattern Wiki
MSDN: Implementing Singleton in C#
Clarification of the article on C#Indepth on Stack overflow - by the author himself

c#: (Static) Class-Level Variables

This is definitely a bit of a noob question, but my searches so afar haven't cleared the issue up for me.
A want a particular console app to store several class-level variables. In one case, I want to store a copy of my logging object, which I'll use in various places within the class. In another case, I want to store a simple type, a int value actually, which is only going to be used internally (doesn't need to be a property).
It appears that unless I specify these variables as static, I can't use them in Main() and beyond.
My understanding of static objects is that their values are shared across all instances of an object. Under normal operation, I'd expect their to be only one instance of my app, so this issue isn't a problem - but it has highlighted a lack of understanding on my part of something that is fairly fundamental.
In the case, of my logging object, I could see a case for making it static - sharing a log across multiple instances might be a benefit. However, it might not be the case... In the case of my int, I'd certainly never want this to be shared across instances.
So...
Am I misunderstanding the theory behind this?
Is there a different way I should be declaring and using my class-level variables?
Should I be avoiding using them? I could simply pass values as parameters from function to function, though it seems little a lot for work for no apparent gain.
EDIT: OK, the message is clear - my understanding of statics was largely correct, but the problem was one of structure and approach. Thanks for your replies.
Just encapsulate your application in another class, which you create and execute on the Main method:
class MyApp {
private MyLog lol = new MyLog();
private int myInt = 0;
public void Execute() {
// ...
}
}
class Program {
public static void Main() {
new MyApp().Execute();
}
}
You can still make the log field static if you want.
You should be creating a class outside of your Main function, and then creating an instance of that class from within Main.
EG
class MyConsoleApp
{
public static void Main()
{
MyClass mc = new MyClass();
}
}
Class MyClass
{
private MyLog lol as new MyLog();
private int myInt = 0;
}
The issue here is more or less purely syntactical: Because a static method can only access static fields, and the Main() method has to be static, this requires the used variables to be static. You never create an instance of the MyConsoleApp class.
Not really much theory here, only pragmatic requirements...
Thomas

Is it bad practice to have state in a static class?

I would like to do something like this:
public class Foo {
// Probably really a Guid, but I'm using a string here for simplicity's sake.
string Id { get; set; }
int Data { get; set; }
public Foo (int data) {
...
}
...
}
public static class FooManager {
Dictionary<string, Foo> foos = new Dictionary<string, Foo> ();
public static Foo Get (string id) {
return foos [id];
}
public static Foo Add (int data) {
Foo foo = new Foo (data);
foos.Add (foo.Id, foo);
return foo;
}
public static bool Remove (string id) {
return foos.Remove (id);
}
...
// Other members, perhaps events for when Foos are added or removed, etc.
}
This would allow me to manage the global collection of Foos from anywhere. However, I've been told that static classes should always be stateless--you shouldn't use them to store global data. Global data in general seems to be frowned upon. If I shouldn't use a static class, what is the right way to approach this problem?
Note: I did find a similar question, but the answer given doesn't really apply in my case.
Who stays that static classes should be stateless? Static means stated.
Just know how static classes work in the CLR:
You can't control the time when static constructors are called.
Static classes have a separate state for each calling program.
Also be aware of concurrency issues.
As a side note, it amazes me how often people say "Don't use X." It would be like someone walking into your toolshed and pointing to half a dozen tools and saying, "Those tools are bad practice." It doesn't make sense.
Global data is both powerful and a common source of problem, that's why techniques like dependency injection are used. You can think of it as a normal decoupling problem. Having global data that is referenced directly in a lot of places in your program makes a strong coupling between that global data and all those places.
In your example however you have isolated the access to the data into a class, which controls the exact details of the access of the global data. As some global data is often inevitable, I think that this is a good approach.
You can for example compare to how app.config and web.config are used through the .NET framework. They are accessed through a static class System.Configuration.ConfigurationManager with a static property AppSettings, which hides a away the details of how to reach the global data.
What you seem to be looking for here is a singleton class, not a static class. Static classes and methods should be referred for stateless routines. A singleton class gets instantiated once and only once per application run and has the full functionality of a class as such. Every time that you reference it in the future, you will get back the exact same instance with the exact same member properties.
The first google result for "C# singleton" seems to have a pretty decent explanation for implementation. http://www.yoda.arachsys.com/csharp/singleton.html
It's not generally bad. In some rare cases it's neccessary to do it that way than implementing something else with large overhead.
But it's recommended to watch for threadsafety.
You should lock every call to your dictionary so that only one thread can access it at one time.
private static readonly object LockStaticFields = new object();
public static Foo Add (int data) {
lock(LockStaticFields)
{
Foo foo = new Foo (data);
foos.Add (foo.Id, foo);
return foo;
}
}
Use a read only static property in your class, this property will be the same across all instances of the class. Increment it and decrement as needed from the constructor, etc.
I use lists in static classes all the time for things that will never (or extremely rarely) change - handy for for loading pick lists and such without hitting the db every time. Since I don't allow changes, I don't have to worry about locking/access control.
One other thing to take into consideration is the application itself and the budget for it. Is there really a need for something more complex than a static class?

Locking critical section in object used across multiple threads

I've got a class that is instantiated within any number of threads that are spooled up as needed. This means that any number of instantiated versions of this class can be used at any one time, and there's a portion of this class that needs to be locked to prevent concurrent access.
To prevent data issues between the various threads, I needed a way to lock a section of code from the other instantiated versions of the class in other threads. Since there can be multiple instantiated versions of this class running around, I can't just use a private member variable to lock (and I know not to use the Type, or anything publicly accessible); so I used a private static member variable.
Is that a reasonable approach to this problem? Or is there a better solution?
Sample code below:
public class MyClass
{
private static object LockingVar = new object();
public void MyPublicMethod()
{
lock (LockingVar)
{
// Do some critical code
}
}
EDIT
MyPublicMethod is making calls to a local SQLExpress instance, it can perform selects in addition to updates and inserts, so it needs to finish before another thread gets in there and mucks it up.
Looks fine to me. I'd also mark the LockingVar as readonly.
Yes, with your sample code, you'll achieve a global critical section on the method for all instances of the class.
If that's what you're looking for (and you have to ask yourself if you really want to have only ever one thread running that method at a time), you can also use the [MethodImpl(MethodImplOptions.Synchronized)] which gets you basically the same feature.
[MethodImpl(MethodImplOptions.Synchronized)]
public static void MyPublicMethod()
{
// Do some critical code
}
Note: this amounts to write lock(this){} if it's a instance method or lock(typeof(MyClass)) if it's a class (static) method. Both are frown upon, so your lock(obj) pattern is better.
From MSDN:
Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.
http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
Therefore your implementation seems to be right.

Categories

Resources