Static Keyword in C#

Static Keyword in C# with Examples

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 understand the need and use of Static Keyword in C# with examples.

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 the C# Static Keyword with an example. First, 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 into 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 checks 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 in the class CountryMaster.cs file, then you will see that, it is private, so in order to use that property in the Customer class, first, we need to change it to the 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 is defined in the Customer class rather than writing the complete logic here. Further, if you notice, the IsEmpty method of the Customer class is private, so in order to use that method in CountryMaster class, we need to change it to the 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 the Customer class so we made the ComputerName property 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 we made the IsEmpty method as public. As long as we did this, we violate the encapsulation principle.

How we are violating the Encapsulation Principle?

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, 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 the CountryMaster object as we are exposing the ComputerName property to the external world that 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 (i.e. Encapsulation Principle). In order to achieve both, let us add a new class and then move those two functions into that 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;
        }
    }
}

Please remove the IsEmpty() method from the Customer class and the ComputerName property from the CountryMaster class. Now both the logic which violates the OOPs principle has been moved to 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 the 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 GetComputerName and IsEmpty 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
            }
        }
    }
}

As we centralized the IsEmpty and GetComputerName method in the CommonTask class, we can use these methods in both the Customer and CountryMaster classes. 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 the 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 and properties that 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 to this CommonTask class.
  3. So, in simple words, we can say that this is a fixed class i.e. a class with a fixed behavior. That is, its behavior can not be changed by inheritance, its 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 the OOPs principle on a class?

The answer is by using the 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 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 serves 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 is the static class instantiated?

We cannot apply any OOPs principles to the static class like inheritance, polymorphism, encapsulation, and abstraction. But in the end, it is a class. And at least to use a class it has to be instantiated. If the static class is 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 is 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 examples. I hope you enjoy this article. I would like to have your feedback. Please post your feedback, question, or comments about this article.

7 thoughts on “Static Keyword in C#”

Leave a Reply

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