Static Fields Are Evil, If Not Coded Correctly

My tech-savvy friend recently retweeted a post underscoring the perils of misusing static fields in Microsoft .NET. Interestingly, I had just had a conversation about this very subject with another software engineer. It brought to mind an incident I tackled for an insurance company concerning data corruption. I’ll narrate that tale towards the conclusion of this article. For now, let’s explore the nuances of employing the static keyword in .NET, focusing particularly on coding static fields within non-static classes.

In Microsoft .NET, a static field is a variable linked to a type rather than to an instance of the type. This implies that the value of the static field is shared among all instances of the type, rather than being unique to each individual instance.

Static fields are declared using the “static” keyword, and they can be accessed using the name of the type rather than an instance of the type. For instance, take a look at the following class excerpt from my OOS Spargine:

public static class App
{
    private static readonly Lazy<AppInfo> _appInfo = new(() => InitAppInfo());

    // Code removed for brevity
}

In this example, the static field _appInfo is initialized when the class is created, and in this scenario, data gathering is deferred until the field is first accessed.

Static fields are often utilized to store data shared across all instances of a type, such as a counter keeping track of how many instances of the type have been created, or a configuration setting common to all instances of the type.

It’s crucial to recognize that static fields can pose challenges with concurrency and thread safety, as multiple threads might attempt to access and modify the same static field concurrently. To mitigate such issues, it’s advisable to employ thread-safe techniques like locking or utilizing the Interlocked class when dealing with static fields in a multi-threaded environment.

Mitigating Risks: Proper Handling of Static Fields in Software Development

Improper use of static fields can indeed pose significant risks, especially when developers are not well-versed in their memory behavior. Initializing a static field keeps it in memory until the application terminates, regardless of ongoing necessity. Thus, developers must exercise caution when deciding what data types to store in these fields and the associated memory requirements.

Consider an example in an ASP.NET website: when user Susan logs in, a CurrentUser object is created, fetching and storing her personal information from the database based on her email address. This information is then stored in a private static field. Subsequently, when the GetUser() method is invoked, Susan’s details are retrieved to facilitate her login. However, if John logs in afterward, a new CurrentUser object is instantiated, loading John’s data and overwriting Susan’s. This can lead to incorrect data presentation, like displaying John’s information when Susan’s details are requested.

This scenario underscores the importance of minimizing the use of static fields unless absolutely necessary, and thoroughly evaluating the potential risks and benefits before incorporating them into a codebase.

Resolving Critical Website Vulnerability: A Case Study in Code Analysis and Developer Collaboration

During the mid-2000s, I was employed by a respected consulting firm in San Diego, California. Our frequent collaborations included working with companies like Microsoft. One day, a local insurance company sought our assistance urgently. They faced a troubling issue: their website was inadvertently displaying personal information from unrelated customers during the new user signup process. Given the sensitivity of such data, it was imperative to rectify the situation swiftly to avoid potential legal repercussions or fines.

Upon reaching the company premises, the manager outlined the persistent problem they had grappled with for over a month. I sat down with the developer at her workstation to investigate the matter. After approximately two hours, I identified that the class field responsible for storing users’ personal information was declared as static. I provided an explanation on how static fields operate and persuaded her to remove the “static” designation from the field definition. This straightforward adjustment successfully resolved the issue.

The development manager expressed satisfaction with my prompt identification of the problem and tasked me with conducting a comprehensive review of the entire codebase. However, my enthusiasm waned upon discovering that I would not have direct access to the source code. Instead, I was provided with a printed copy for review. This underscored the critical importance of maintaining well-documented and consistently formatted code, as its presentation can significantly impact comprehension and analysis.

Following two weeks of thorough examination, I presented management with my findings and suggestions for enhancements. Regrettably, the developer rebuffed my recommendations and adamantly refused to heed my advice. Faced with her reluctance to cooperate, I advised management to seek a replacement for the lead developer role. Consequently, they initiated the search and appointed a new lead developer a month later.

Summary

When I review code and encounter a static field, it immediately raises a red flag, prompting me to ensure its proper usage. After absorbing the insights from this article, I trust you’ll approach static fields with the same caution. Embracing this perspective will lead to the crafting of superior, more stable code.

Should you have any queries or thoughts about the content discussed in this article, feel free to share them in the comments section below. I’m eager to engage with you.

2 thoughts on “Static Fields Are Evil, If Not Coded Correctly

  1. class Foo
    static Foo bar = new Foo();
    ….
    bar = null;

    Only the memory required to hold a reference to an object remains in memory. You need ALOT of these to have an impact…

    Now if you do not have that “clearing” of the reference somewhere then indeed the instance of Foo and all things is refereces will last forever.

    Note that BindingSource and ToolTip both register (indirectly) their instances with a static, and if you dont clear them up properly you will have memory problems [that was my life this past February ]

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.