PowerShell classes can contain static methods and properties:
class stack {
[string]
$name
[DateTime]
static $date = (GET-DATE)
stack($name) {
$this.name = $name
}
static [void] hello() {
Write-Host 'hello'
}
}
A couple use cases I've found so far for static methods:
- organize my functions within a common context of a class.
- I believe I have read somewhere that static methods are much more performant than functions. I've never verified it myself, though.
And for static properties:
- They define variables that can be called from any scope, especially from within other classes without needing to pass the variable into the class as an argument.
I have the feeling that my reasons for using static methods / properties are pretty underdeveloped. Static properties in particular seem like more laborious alternatives to simple variables, although the omni-scope availability is very nice if you do run into that use case.
So my questions:
- What use cases have you found for static methods/properties?
- Does it ever make sense to set a static property without a default value?
CodePudding user response:
Since PowerShell was given, I will give a .NET-centric answer.
Ultimately the details will vary from language to language, but static class instances are typically instantiated only once the first time a static member is called on it. This means you will have a single instance created for any code which needs to call it. Conversely, being able to call the constructor of a non-static class means you can create as many instances as times you can call the constructor. For classes with both static and non-static members, the static members are still only created a single time in memory for the static instance.
Create static methods if the method does not rely on instance data to get the job done. For example, a string
class might include static utility methods that still require a source string to be passed in. Let's look at the signature of the built-in String.IsNullOrEmpty
static method:
[string]::IsNullOrEmpty
# OverloadDefinitions
# -------------------
# static bool IsNullOrEmpty(string value)
IsNullOrEmpty
makes sense to define as static because it does not make sense to have it operate on an instantiated string object instead. Think about what the method does. It checks for:
- A
null
value; or - A value of
[string]::Empty
It is a utility method in order check the conditions above against another string. If this were not a static method, we cannot check for a null
string as the instance doesn't exist
(you can't call a method on a null-valued expression). Even if we could have a null
string and call the method, we would first need to create a string object to use it, which would allocate memory for IsNullOrEmpty
for every single string object. None of this is efficient considering it's a utility method that can easily have a valid string passed into it.
The main benefit here is that you do not need to allocate memory for every static method for every string
object created. As explained above, the static methods are instantiated only once for the static instance.
The same goes for properties, although oftentimes static properties are read only. One example might be a System Properties class, and the OS version may be a static string. Consider the static property I used above, [string]::Empty
. If this were not a static property, we run into the same pitfalls as defining IsNullOrEmpty
as a non-static member: it will get allocated more often than it needs to be, and we need to first create a non-null instance to use it. The latter occurs with static classes behind the scenes, so you are free to use static members without worrying about initialization or instantiation.
Note: Create a static class if all the members are planned to be static, as it does not make sense to create an instance when it would hold no stateful information. Static classes in .NET are classes that cannot be directly instantiated, except for a single static constructor.
To summarize, it's mostly about memory management. Static members are only created once during the lifetime of the program, while instance (non-static) members are created for each instance of the object created with new
.