Advantages to Using Private Static Methods - c#

When creating a class that has internal private methods, usually to reduce code duplication, that don't require the use of any instance fields, are there performance or memory advantages to declaring the method as static?
Example:
foreach (XmlElement element in xmlDoc.DocumentElement.SelectNodes("sample"))
{
string first = GetInnerXml(element, ".//first");
string second = GetInnerXml(element, ".//second");
string third = GetInnerXml(element, ".//third");
}
...
private static string GetInnerXml(XmlElement element, string nodeName)
{
return GetInnerXml(element, nodeName, null);
}
private static string GetInnerXml(XmlElement element, string nodeName, string defaultValue)
{
XmlNode node = element.SelectSingleNode(nodeName);
return node == null ? defaultValue : node.InnerXml;
}
Is there any advantage to declaring the GetInnerXml() methods as static? No opinion responses please, I have an opinion.

From the FxCop rule page on this:
After you mark the methods as static, the compiler will emit non-virtual call sites to these members. Emitting non-virtual call sites will prevent a check at runtime for each call that ensures that the current object pointer is non-null. This can result in a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue.

When I'm writing a class, most methods fall into two categories:
Methods that use/change the current instance's state.
Helper methods that don't use/change the current object's state, but help me compute values I need elsewhere.
Static methods are useful, because just by looking at its signature, you know that the calling it doesn't use or modify the current instance's state.
Take this example:
public class Library
{
private static Book findBook(List<Book> books, string title)
{
// code goes here
}
}
If an instance of library's state ever gets screwed up, and I'm trying to figure out why, I can rule out findBook as the culprit, just from its signature.
I try to communicate as much as I can with a method or function's signature, and this is an excellent way to do that.

A call to a static method generates a call instruction in Microsoft intermediate language (MSIL), whereas a call to an instance method generates a callvirt instruction, which also checks for a null object references. However, most of the time the performance difference between the two is not significant.
Source: MSDN - https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/79b3xss3(v=vs.110)

Yes, the compiler does not need to pass the implicit this pointer to static methods. Even if you don't use it in your instance method, it is still being passed.

It'll be slightly quicker as there is no this parameter passed (although the performance cost of calling the method is probably considerably more than this saving).
I'd say the best reason I can think of for private static methods is that it means you can't accidentally change the object (as there's no this pointer).

This forces you to remember to also declare any class-scoped members the function uses as static as well, which should save the memory of creating those items for each instance.

I very much prefer all private methods to be static unless they really can't be. I would much prefer the following:
public class MyClass
{
private readonly MyDependency _dependency;
public MyClass(MyDependency dependency)
{
_dependency = dependency;
}
public int CalculateHardStuff()
{
var intermediate = StepOne(_dependency);
return StepTwo(intermediate);
}
private static int StepOne(MyDependency dependency)
{
return dependency.GetFirst3Primes().Sum();
}
private static int StepTwo(int intermediate)
{
return (intermediate + 5)/4;
}
}
public class MyDependency
{
public IEnumerable<int> GetFirst3Primes()
{
yield return 2;
yield return 3;
yield return 5;
}
}
over every method accessing the instance field. Why is this? Because as this process of calculating becomes more complex and the class ends up with 15 private helper methods, then I REALLY want to be able to pull them out into a new class that encapsulates a subset of the steps in a semantically meaningful way.
When MyClass gets more dependencies because we need logging and also need to notify a web service (please excuse the cliche examples), then it's really helpful to easily see what methods have which dependencies.
Tools like R# lets you extract a class from a set of private static methods in a few keystrokes. Try doing it when all private helper methods are tightly coupled to the instance field and you'll see it can be quite a headache.

As has already been stated, there are many advantages to static methods. However; keep in mind that they will live on the heap for the life of the application. I recently spent a day tracking down a memory leak in a Windows Service... the leak was caused by private static methods inside a class that implemented IDisposable and was consistently called from a using statement. Each time this class was created, memory was reserved on the heap for the static methods within the class, unfortunately, when the class was disposed of, the memory for the static methods was not released. This caused the memory footprint of this service to consume the available memory of the server within a couple of days with predictable results.

Related

Static variable population best practice

I have a class Meterage which I expect to be instantiated several times, probably in quick succession. Each class will need to know the location of the dropbox folder in the executing machine, and I have code for this.
The class currently has a variable:
private string dropboxPath = string.Empty;
to hold the path, but I am considering making this a static to save repeated execution of
this.LocateDropboxFolder();
in the constructor. But I am a little concerned by the switch: what if two constructors try to set this at the same time? Would this code in the constructor be safe (LocateDropboxFolder becomes static too in this example):
public Meterage()
{
if (dropboxPath == string.Empty)
{
LocateDropboxFolder();
}
}
I think my concerns are perhaps irrelevant as long as I don't have construction occurring in multiple threads?
If the field is made static then static field initializers or static constructors are the easy way to initialize them. This will be executed at most once in a thread safe manner.
private static string dropboxPath;
static Meterage()
{
LocateDropboxFolder();
}
If you don't want to re-assign the field I suggest you to use readonly modifier, then the code should look like:
private static readonly string dropboxPath;
static Meterage()
{
dropboxPath = LocateDropboxFolder();
}
LocateDropboxFolder needs to return a string in this case.
Variables declared outside the constructor are evaluated before the constructor. Then the constructor will evaluate it.
Do remember that you will end up have only one dropBoxPath. If this is intended, it is okay to do so. Optionally, make LocateDropboxFolder a static method and call it from the static constructor.
If you want to prevent other constructors to overwrite the default, try this:
if (string.IsNullOrEmpty(dropboxPath))
{
LocateDropboxFolder();
}
Or, in a static constructor (at most called once):
static Meterage()
{
LocateDropboxFolder();
}
private static LocateDropboxFolder()
{
...
}
Your example will be safe provided your code is executing synchronously. If multiple instances are created, their constructors will be called in the order they are created.
On the first run through, LocateDropboxFolder() will execute. When this completes, dropboxPath will be set.
On the second constructor execution, LocateDropboxFolder() will not execute because dropboxPath will no longer equal string.Empty (provided 'LocateDropboxFolder()' does not return string.Empty.
However, if LocateDropboxFolder() is asynchronous or the objects are instantiated on different threads, then it is possible to create a second Meterage instance before dropBoxPath has been set by the LocateDropboxFolder() function. As such, multiple calls to the function will likely be made.
If you wish to guard against multithreading errors like this, you could consider using lock statements.
You might potentially end up running the LocateDropboxFolder multiple times if the object tries to be constructed multiple times in close succession from multiple threads. As long as the method returns the same result every time though this shouldn't be a problem since it will still be using the same value.
Additionally if you are setting the value of dropboxPath in the constructor then there is no point setting a default value for it. I'd just declare it (and not assign it) and then check for null in your constructor.
I hava a feeling that your Meterage class is breaking a Single Responsibility Principle. What has the meterage to do with a file access? I would say you have 2 concerns here: your Meterage and, let's say, FolderLocator. the second one should have some property or method like Dropbox which could use lazy evaluation pattern. It should be instantiated once and this single instance can be injected to each Metarage instance.
Maybe not FolderLocator but FileSystem with some more methods than just a single property? Nos sure what you're actually doing. Anyway - make an interface for this. That would allow unit testing without using the actual Dropbox folder.

What is lazy instantiation

Is lazy instantiation about using less code but getting the same result? Surely this is generally a good thing to do (providing making the code to short / efficient doesn't damage readability/maintainability).
Please refer to this lazy instantiation:
public sealed class Singleton
{
private Singleton()
{
}
public static Singleton Instance { get { return Nested.instance; } }
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
There is no private property of Instance (I know it's implicit) - is it that which makes it lazy - the fact we don't have a setter within the public static Singleton Instance property?
Lets say we have a field of a type that is expensive to construct
class Foo
{
public readonly Expensive expensive = new Expensive();
...
}
The problem with this code is that instansiating Foo incurs the performance cost of instansiating Expensive - whether-or-not the Expensive field is ever accessed. The obvious answer is to construct the instance on demand or lazily instansiate the field:
class Foo
{
Expensive _expensive;
public Expensive
{
get
{
if (_expensive == null) _expensive = new Expensive();
return _expensive;
}
}
...
}
This is lazy instansiation.
Lazy initialization is a practice whereby you only load or initialize an object when you first need it.
Potentially, this can give you a big performance boost, especially if you have a vast amount of components in your application.
Look at the Wikipedia page for a greater insight (it features coded examples).
No, lazy instantiation means not spending any time and resources creating something until you actually need it.
In your singleton example, the instance is just an empty reference, until it's actually used. When it's used, then you spend the resources to instantiate the object with a new.
Lazy initialization of an object means that its creation is deferred until it is first used.
For complete reference see msdn post Lazy Initialization
In your above code, the instance of the singleton class is not created until you call it.
So, your program will not use resources until your code gets called.
It's lazy because the instance of the class Singleton isn't created until the first time you ask for it.

C# static garbage collector?

I have a simple class which has a static constructor and a instance constructor. Now when i initialized the class , both static and instance constructor are called. Only static is referred once in a application domain . Can i again call the same class initialization and static constructor initialize again? I have tried but it didn't happen? Is there any way we can call static constructor again in main() method after using garbage collection on the class.
Here is the code:
public class Employee
{
public Employee()
{
Console.WriteLine("Instance constructor called");
}
static Employee()
{
Console.WriteLine("Static constructor called");
}
~Employee()
{
//Dispose();
}
}
Now in main method call:
static void Main(string[] args)
{
Employee emp = new Employee();
Employee emp = new Employee();
}
Output:
Static constructor called
Instance constructor called
Instance constructor called
Now the static didn't called again. Because it is called once in application domain. But is their any way we could call it again without unloading application domain. Can we use GC class over here?
Thanks.
Pal
Unless you prod it with reflection, the static constructor (or more generally, the type initializer) is only executed once per concrete class, per AppDomain.
Note that for generics, using different type arguments you'll get different concrete classes:
public class Foo<T>
{
Foo()
{
Console.WriteLine("T={0}", typeof(T));
}
public static void DummyMethod() {}
}
...
Foo<int>.DummyMethod(); // Executes static constructor first
Foo<string>.DummyMethod(); // Executes static constructor first
Foo<string>.DummyMethod(); // Type is already initialized; no more output
Not possible. The CLR keeps an internal status bit that tracks whether the type initializer was started. It cannot run again. That status bit is indeed stored in the loader heap as part of the AppDomain state. The workaround is simple, just add a static method to the class.
The point of a constructor is to put things into a desired initial valid state.
An instance constructor puts an instance into an initial valid state.
An instance constructor that takes arguments puts an instance into a initial valid state that reflects its arguments.
A static constructor puts the type into an initial valid state. E.g. initialising static members used by the class' static methods or shared by all instances.
Ideally all methods will leave the object and the type in a valid state, but constructors differ in being responsible for getting it into one in the first place.
Any attempt to call a constructor twice is therefore a mistake, since "put it into an initial valid state again" isn't something you can logically do twice ("initial" and "again" don't work well in the same clause). We are helped by the compiler (in it refusing to compile) and the language (in there being no way to express this) from doing such a thing.
And, being a logical impossibility it isn't something you can actually want to do (well, I can want to draw a triangle with more than 3 sides, but only to say that I did). This suggests that you are using your constructor to do something other than setting up an initial valid state.
Doing anything other than establishing such a valid state in a constructor is (as is failing to do so) at best an optimisation, quite often a serious design flaw and quite possibly (worse of all because it goes unfixed longer) an attempted optimisation that is really a serious design flaw.
One sign that your attempt at an optimisation is really a design flaw is a desire to call a static constructor more than once, or to call an instance constructor more than once on the same object.
Identify the desired repeatable behaviour, move it into a separate method, and have it called as needed from both the constructor and elsewhere. Then double check your design's logic, as this is quite a serious mistake to find in a class design and suggests you've got deeper problems.

Is a class instantiated when a static method is called in a non-static class?

Exactly what happens when Foo.SomeCheck() is called in the Bar class? Is an instance of Foo created in order to call SomeCheck()? If so, is this instance stored on the heap, and is it ever collected through garbage collection?
public class Foo() {
public static bool SomeCheck() {
return true;
}
}
public class Bar() {
public void SomeMethod() {
// what happens when we access Foo to call SomeCheck?
if (Foo.SomeCheck()) {
//do something
}
}
}
Static methods differ from instance methods in that no instance of the class they belong to needs to have been created for them to be called. When you call a static method, you in fact make the call using the name of the type rather than an instance of the type - which should reinforce the idea that static methods are not called on instances. That bears repeating and emphasis: No instance of a class is required to call a public static method of that class.
Now, your example is malformed, but presumably, the line: if( Foo.SomeCheck() ) is calling the SomeCheck static method using the name of the type: Foo - not an instance. Bar however, has to be instantiated in order to make this call - however, in your example, you don't have a well-formed instance of Bar. Code generally has to exist inside a method (or a member initializer) - which you don't have here.
To respond to the other parts of your question. Assuming the code in question is part of an instance method, something has to instantiate Bar - and invoke that method. That something would have to create or otherwise acquire an instance of Bar. Reference types will always be creted on the heap - but that's largely irrelevant here.
As for garbage collection, you normally shouldn't worry about this. The .NET runtime makes sure to cleanup instances that are not referenced from any root object in your program. Roots are typically instances that reside somewhere on the callstack or are referenced by static members of one type or another. Since we don't see any code here that creates or references Bar it's impossible to say when it will be collected. For instance, if Bar is a singleton and stored somewhere in a static variable, it may live for a very long time - perhaps the entire lifetime of the program. You can't really know without seeing all of the code that manipulates and manages Bar.
I highly recommend reading the following article:
Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects
It explains how the .NET runtime works at a low level, and explains internal nuances like Loader Heaps and how static classes/members work. Technically speaking, there IS an initial instantiation of the 'static instnace' of a classes static members. However, this initiation is handled by the runtime in a different way than it is handled for class instances. Static classes are stored on loader heaps, which are not GC managed. Loader heaps are allocated and grown in a static manner, and are not compacted. The article is a great read, and should give you a thourough understanding of how the CLR operates.
(NOTE: I am not certain of how valid this article is for .NET 4. I do know that there were GC changes in .NET 4, however I am not sure how many fundamental runtime changes there are. The introduction of the DLR and other features may deviate from the explanation in the above article to some degree.)
Foo does not need to be instantiated, neither will it get instantied upon the SomeCheck static method call as per result, you would get the value returned by the method itself, and not an instance of the class.
Please have a look at these references for further details:
Static vs Non-Static Methods;
Static Classes and Static Class Members (C# Programming Guide).
I do hope this helps! =)
It depends on the implementation of SomeMethod. The method will have to be invoked from somewhere, presumably a "driver" class which would instantiate Bar and call SomeMethod. For example:
public class Driver
{
public static void Main()
{
Bar bar = new Bar();
bar.SomeMethod();
}
}
Given your current implementation of SomeMethod, yes, you'd have to instantiate it.
However, as long as SomeMethod only makes a call to another static method, we could make make it static too. In which case you wouldn't have to create an instance of Bar to invoke the method. i.e.
public class Driver
{
public static void Main()
{
Bar.SomeMethod();
}
}
public class Manipulate
{
public static int Main(string[] args) {
Bar bar = new Bar();
bar.BarFoo();
Console.ReadKey();
return 0;
}
}
public class Foo {
public static bool SomeCheck() {
return true;
}
}
public class Bar {
// what happens when we access Foo to call SomeCheck?
public void BarFoo() {
if (Foo.SomeCheck()) {
Console.WriteLine("Hello am true");
}
}
}
Yes you need to create an instance of Bar but not for Foo class since it is a static metod. Only difference is, the static methods are called at class level(compile time) rather than object level(run time), so you don't need to instantiate the Foo class.

Static method and threads

I have put one question on MSDN forum but got two opposite answers. In general I am intersted how threading works with static classes. If my code calls this(below) static method from 10 threads at the same time, is it thread safe? I mean, how the code flows behind the scenes? Does every thread executes the code within itself (like I think it does with non-static classes) or it is different with static method and, because its static, all threads try to reach the code and collide? Thanks!
public static class A
{
static void Method(object parameter)
{
SqlCeConnection = .....
}
}
Link to MSDN question: Here
PS: I am sorry due to IE page errors I cannot click on "Add comment" or "Answer", Jon Skeet answer is good (as usually :)
It's exactly the same as with non-static classes. Being static doesn't affect anything really - except that static methods are generally expected to be thread-safe. They're not automatically thread-safe, but you should make sure that you implement them in a thread-safe manner.
If the code doesn't use any shared state, it should be fine. And yes, without any locking, all the threads can be executing the same method concurrently.
A nice example can be singleton pattern.In this all you need is a single instance for a given class and that can be made sure by making the constructor private and giving a static method or property to access the instance.Following code snippets highlight the same :-
class MyClass
{
private MyClass()
{
}
public static MyClass Instance
{
get
{
lock(typeof(MyClass))
{
if(__instance == null)
__instance = new MyClass();
}
return __instance;
}
}
}
Since the "Instance" method is marked static(thread consistent access) , but in multi threaded envoirnment you need to manully take care of it(using lock).

Categories