Classes With Static and Non-Static Methods in C#
Firstly, we will cover the difference between static and non-static methods and then move further.
Static Methods in C#
A static method belongs to the class, not the object (instance of the class), or we can say that "A static method is a method that belongs to a class rather than an instance of a class." This is the whole simple definition, and it is a very simple one, but it requires knowledge and explanation so that we will see our first example.
public partial class Taxpayer
{
public string UniqueIdentificationNumber { get; set; }
public string Password { get; set; }
public bool CheckUIN()
{
var regex = new Regex(@"^\w+$");
var match = regex.Match(UniqueIdentificationNumber);
return match.Success;
}
public static bool CheckPassword(string password)
{
return password.Any(c => char.IsUpper(c))
&& password.Any(c => char.IsLower(c))
&& password.Any(c => char.IsNumber(c));
}
public bool CheckTaxpayer()
{
return CheckUIN() && CheckPassword(Password);
}
}
In the above example, there is the Taxpayer class; this class contains two properties named as UniqueIdentificationNumber and Password; besides these properties, there are three methods also one is for checking the UIN number (Unique Identification Number), the second one is for checking password and the last one is for checking the whole Taxpayer object.
Methods CheckUIN and CheckTaxpayer are known as instance class methods, and on the other hand, the CheckPassword method is static. The Taxpayer instance calls the first two to access both properties because properties are also part of the Taxpayer instance. Still, the CheckPassword can't access the properties because it belongs to the Taxpayer type, not the instance, so in that case, we need to provide the value as a parameter.
var taxpayer = new Taxpayer()
{
UniqueIdentificationNumber = "AGAPO897P",
Password = "ThisIs3asyPa$$word"
};
Console.WriteLine($"Unique Identifire Number is correct: {taxpayer.CheckUIN()}");
Console.WriteLine($"Password is correct: {Taxpayer.CheckPassword(taxpayer.Password)}");
Console.WriteLine($"Whole object is correct: {taxpayer.CheckTaxpayer()}");
The CheckEmail() and CheckTaxpayer() methods are used as we are used to, as a method on the Taxpayer object. But the CheckPassword() method can't be accessed as a typical method on an object. Remember, it does not exist on an object but on a type Taxpayer, so we need to use the type and write Taxpayer.CheckPassword(). This method also expects a parameter, and we need to provide one. Because we are interested in the taxpayer's password, we provide taxpayer.Password as a parameter.
Why Can't Static Methods Access Object Properties?
The real question is, "Why can instance methods access object properties?"
The answer to the above question is Compiler. The .Net compiler secretly adds a special parameter "this" to every object method, creating something similar to this behind the scenes:
public bool CheckUIN(Taxpayer this)
{
var regex = new Regex(@"^\w+$");
var match = regex.Match(this.UniqueIdentificationNumber);
return match.Success;
}
public bool CheckTaxpayer(Taxpayer this)
{
return this.CheckUIN() && CheckPassword(this.Password);
}
public static bool CheckPassword(string password)
{
return password.Any(c => char.IsUpper(c))
&& password.Any(c => char.IsLower(c))
&& password.Any(c => char.IsNumber(c));
}
Note. To be clear, this is not a literal representation of what is happening behind the scenes but an accurate enough illustration for our purpose.
UniqueIdentificationNumber for improved precision. Here we see explicit access to the property UniqueIdentificationNumber as this.UniqueIdentificationNumber. Both versions are correct, and some people even prefer or demand the second version.
The "this" keyword clarifies how instance methods access properties and why static methods cannot.
Why Use Static Methods?
At this point, we might ask ourselves why we would even bother utilizing static methods. We've seen that non-static methods can access properties and are easier to use, right? Is there even a good use case back in our first example? Consider this: To use a method CheckUIN(), we have first to create an object of type Taxpayer and then set an UniqueIdentificationNumber property. But for checking a password, no object instantiation is required. We can call a method Taxpayer.CheckPassword() and check the provided password in a single line of code.
General Usage Rule
Any method that doesn't change any state or require anything about an object to do its work is a good candidate to be made static. But in that case, we should also ask ourselves if the method belongs to the class. Does it prevent the class from adhering to the Single Responsibility Principle?
That is a good question that is not always easy to answer. It may help if we answer two further questions. First, is the method related to this class? And second, is the method name with a class name more informational than just a method name without one? We ask the second question because we can't call a static method without a class name.
If the method can't be thought of as related to the class, then it does not belong within it. And if a class name before the method name doesn't add any useful context, then such a method might belong in a more general or utility class.
Some important points are also mentioned below,
- We can't override the static method, but we can hide the implementation of any static method in the base object and define a new implementation in the derived class.
- We can overload a static method. It is perfectly acceptable to have two or more static methods with the same name as long as they use different parameter sets.