Static in C#

Static in C#

In this article, I am going to discuss why do we need the keyword Static in C# with examples. Please read our previous article, where we discussed C# String in detail. At the end of this article, I am sure you will be understand the need and use of Static Keyword in C#.

Why do we need Static Keyword in C#?

If you ask this question to any developers, they most probably answer you that the static keyword is used in Factory Design Pattern, Singleton Design Pattern as well as used for data sharing, etc. But I think, the static keyword is used for three basic purposes. And in this article, we will discuss these three purposes in detail. I hope you are going to enjoy this article.

Example to understand the Static Keyword in C#:

Let us understand the need and use of C# Static Keyword with an example. Create a console application with the name StaticKeyowrdDemo.

CountryMaster.cs:

Once you created the Console application, then create a class file with the name CountryMaster.cs and then copy and paste the following code in it.

namespace StaticKeyowrdDemo
{
   public class CountryMaster
    {
        public string CountryCode { get; set; }
        public string CountryName { get; set; }       
        private string ComputerName
        {
            get
            {
                return System.Environment.MachineName;
            }
        }
        public void Insert()
        {

        }
    }
}
Explanation of Above Class:

Here we created the class with three properties and one method. The CountryCode property is going to hold the three letter symbols of the country while the CountryName property holds the full country name. The ComputerName property has the logic to retrieve the current machine name.

The Insert Method inserts the country record into the database and while inserting it also uses the ComputerName property to tells that from which computer this record was inserted.

Customer.cs

Now, create a new class file with the name Customer.cs and then copy and paste the following code in it.

namespace StaticKeyowrdDemo
{
    public class Customer
    {
        public string CustomerCode { get; set; }
        public string CustomerName { get; set; }
        private string MachineName = "";
        private bool IsEmpty(string value)
        {
            if(value.Length > 0)
            {
                return true;
            }

            return false;
        }        
        public void Insert()
        {
            if(IsEmpty(CustomerCode) && IsEmpty(CustomerName))
            {
                //Insert the data
            }
        }
    }
}
Explanation of Above Code:

The CustomerCode property is going to hold the three letter code of the customer while the CustomerName property holds the customer name. The IsEmpty method accepts one value and then check if the value is empty or not. If not empty then return true else return false

The Insert method simply check if both CustomerCode and CustomerName are not empty then insert the customer record into the database.

Here, the problem is with the MachineName variable. The MachineName should have the current computer name while inserting the customer data into the database, so that we can track from which machine this customer data was inserted

If you remember, the CountryMaster class has the logic to retrieve the computer name. Rather than writing the duplicate logic here, we should go and use the logic which is already written in the CountryMaster class, so that we can avoid writing the repeating code or redundant code.

If you check the ComputerName property, then you can that it is private, so in order to use that property in the Customer class, first we need to change it to public as shown in the below image.

Static in C#

Again while inserting the CountryMaster record into the database, we also need to check both CountryCode and CountryName should not be empty. To check if empty or not, we also like to use the IsEmpty method which defined in the Customer class rather than writing the complete logic here. Further if you notice, the IsEmpty method of Customer class is private, so in order to use that method in CountryMaster class, we need to change it to public as shown in the below image.

Why do we need Static Keyword in C#?

The CountryMaster class has logic to retrieve the Computer name and we want to use that logic in Customer class so we made the ComputerName property as public. Similarly, the Customer class has logic check whether a value is empty or not and we also want that logic in the CountryMaster class, so make the IsEmpty method as public. As long as we did we violate the encapsulation principle.

How we are violating the Encapsulation?

Let us understand how we are violating the encapsulation principle. Modify the Program class as shown below. Once you created the Customer class object, then you can see the public member of that class as shown in the below image.

How we are violating the Encapsulation?

As you can see, we have exposed the CustomerCode, CustomerName, Insert and IsEmpty methods. There is a clear violation of abstraction. Abstraction means shows only what is necessary. So, the external person who is consuming your class, he should see and consume the CustomerCode, CustomerName and Insert method. But should not see the IsEmpty method. The IsEmpty method is for internal use i.e. use by other methods not by the consumer of the class. As we make the IsEmpty method as public, we are violating the Encapsulation principle.

In the same way, we also violating the abstraction principle with CountryMaster object as we are exposing the ComputerName property to the external world who is going to consume the class as shown in the below image. The ComputerName property is for internal use only.

Example to understand the Static Keyword in C#:

Note: With the above we are achieving code reusability (reusing the ComputerName and IsEmpty method) but violating the encapsulation principle.

How to solve this problem?

How to solve the above problem means how should we achieve code reusability but without violating the oops principles. In order to achieve both lets add a new class and then move those two function to this class. Create a class file with the name CommonTask.cs and then copy and paste the following code in it.

namespace StaticKeyowrdDemo
{
    public class CommonTask
    {
        public bool IsEmpty(string value)
        {
            if (value.Length > 0)
            {
                return true;
            }

            return false;
        }

        public string GetComputerName()
        {
            return System.Environment.MachineName;
        }
    }
}

Note: Please remove the IsEmpty() method from the Customer class and ComputerName property from the CountryMaster class.

Now both the logic which violates the OOPs principle has been moved the CommonTask class.

Modifying Customer class:

Now modify the Customer class as shown below. As you can see, in the constructor we set the value of MachineName private variable and in the Insert method, we create an instance of CommonTask class and Invoke the IsEmpty method.

namespace StaticKeyowrdDemo
{
    public class Customer
    {
        public string CustomerCode { get; set; }
        public string CustomerName { get; set; }
        private string MachineName = "";

        public Customer()
        {
            CommonTask commonTask = new CommonTask();
            MachineName = commonTask.GetComputerName();
        }
        
        public void Insert()
        {
            CommonTask commonTask = new CommonTask();
            if(!commonTask.IsEmpty(CustomerCode) && !commonTask.IsEmpty(CustomerName))
            {
                //Insert the data
            }
        }
    }
}
Modifying the CountryMaster class:

Please modify the CountryMaster class as shown below. Here, we created the instance of CommonTask and then Invoke the methods.

namespace StaticKeyowrdDemo
{
    public class CountryMaster
    {
        public string CountryCode { get; set; }
        public string CountryName { get; set; }
        private string ComputerName
        {
            get
            {
                CommonTask commonTask = new CommonTask();
                return commonTask.GetComputerName();
            }
        }

        public void Insert()
        {
            CommonTask commonTask = new CommonTask();
            if (!commonTask.IsEmpty(CountryCode) && !commonTask.IsEmpty(CountryName))
            {
                //Insert the data
            }
        }
    }
}

Note: As we centralized the IsEmpty and GetComputerName method in the CommonTask class, we can use this methods in both Customer and CountryMaster class.

The above solution seems to be decent as it does not violate the OOPs Principle and also achieving code reusability and I hope many of you are also agree to it. But there is also some problem.

What is the problem in above solution?

In order to understand the problem, let us first analyze the CommonTask class in a great manner.

Note about CommonTask class:
  1. This CommonTask class is a collection of unrelated methods, properties which are not related to each other. Because it has unrelated methods, properties or logic, it does not represent any real world objects.
  2. As it does not represent any real world objects, so any kind of OOPs principles (inheritance, abstraction, polymorphism, encapsulation) should not be allowed to be applied on this CommonTask class.
  3. So, in simple words, we can say that this is a fixed class i.e. a class with fixed behavior. That is, its behavior can not be changed by inheritance, it’s behavior can not be polymorphised by using either static or dynamic polymorphism. So, we can say that this class is a fixed class or static class.
How do we avoid inheritance, how do we avoid abstract keywords, or how do we avoid OOPs principle on a class?

The answer is by using static keyword. So, you need to mark the CommonTask class as static by using the static keyword. When you mark a class as static, everything inside the class should be static. That means, we also need to mark the IsEmpty and GetComputerName methods as static. So, modify the CommonTask class as shown below.

namespace StaticKeyowrdDemo
{
    public static class CommonTask
    {
        public static bool IsEmpty(string value)
        {
            if (value.Length > 0)
            {
                return true;
            }

            return false;
        }

        public static string GetComputerName()
        {
            return System.Environment.MachineName;
        }
    }
}

Once you make the class as static, then you cannot use the new keyword with the static class to create an instance, rather you need to invoke the IsEmpty and GetComputerName methods by using the class name. Internally only one instance of the static class gets created by CLR which serve all the clients.

Modify the Customer class:

Now modify the Customer class as shown below. As you can see, now we are invoking the GetComputerName and IsEmpty method using the class name i.e. CommonTask.

namespace StaticKeyowrdDemo
{
    public class Customer
    {
        public string CustomerCode { get; set; }
        public string CustomerName { get; set; }
        private string MachineName = "";

        public Customer()
        {
            MachineName = CommonTask.GetComputerName();
        }
        
        public void Insert()
        {
            if(!CommonTask.IsEmpty(CustomerCode) && !CommonTask.IsEmpty(CustomerName))
            {
                //Insert the data
            }
        }
    }
}
Modify the CountryMaster class:

Modify the CountryMaster class as shown below. As you can see in the below code, we are invoking the GetComputerName and IsEmpty method using the class name i.e. CommonTask.

namespace StaticKeyowrdDemo
{
    public class CountryMaster
    {
        public string CountryCode { get; set; }
        public string CountryName { get; set; }
        private string ComputerName
        {
            get
            {
                return CommonTask.GetComputerName();
            }
        }

        public void Insert()
        {
            if (!CommonTask.IsEmpty(CountryCode) && !CommonTask.IsEmpty(CountryName))
            {
                //Insert the data
            }
        }
    }
}
How the static class instantiated?

We cannot applied any OOPs principles to the static class like inheritance, polymorphism, encapsulation and abstraction. But at the end, it is a class. And at least to use a class it has to be instantiated. If the static class not instantiated then we cannot invoke the methods and properties that are present in the static class.

Now let us see how does the instantiation takes place internally of a static class i.e. in our example, it is the CommonTask class.

The CLR (Common Language Runtime) will create only one instance of the CommonTask class irrespective of whether how many times they called from the Customer and CountryMaster class. For better understanding, please have a look at the below image.

How the static class instantiated?

Due to the single instance behavior, the static class are also going to be used to share the common data.

In the next article, I am going to discuss Static vs NonStatic Members in C#. Here, in this article, I try to explain the need and use of the Keyword Static in C# with some examples. I hope you enjoy this article. I would like to have your feedback. Please post your feedback, question, or comments about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *