This rule raises an issue each time a static field is updated from a non-static method or property.
Why is this an issue?
A static field is shared by every instance of the type, so when an instance method or property writes to it, multiple objects — and
multiple threads — can read and modify the same field concurrently. This leads to unintended consequences for other instances or threads: unexpected
values, race conditions and synchronization
problems that are hard to reproduce and debug.
Exceptions
This rule targets unsynchronized writes to shared static state. A reported write can be intentional when the access is properly
synchronized (for example, guarded by a lock or performed through System.Threading.Interlocked), or when the type is only
ever used from a single thread. Review such cases before changing them rather than applying a blind fix.
The rule still raises on the write even when it is guarded, because the check is syntactic. In the following example the access is deliberately synchronized, so the reported issue can be left as-is:
class IdGenerator
{
private static readonly object syncRoot = new();
private static int lastId;
public int Next()
{
lock (syncRoot)
{
return ++lastId; // Noncompliant: reported, but acceptable here because the write is properly synchronized
}
}
}
How to fix it
Decide what the field is really for, then choose one of the following:
- If the value is meant to be shared by all instances, make the enclosing method or property
staticas well, so it is clear the member operates on class-level state. - If the write does not need to be shared between instances, replace the
staticfield with an instance field. - If the field must stay
staticand be written from instance members, guard every access so concurrent updates are safe, for example with alockorInterlocked.
Making a member static or moving state to an instance field changes which object the data belongs to, so make sure the new scope
preserves the behavior the callers expect.
Code examples
Noncompliant code example
class Counter
{
private static int count = 0;
public void Increment()
{
count++; // Noncompliant: an instance method writes to the 'static' field 'count'
}
}
Compliant solution
class Counter
{
private int count = 0; // Each Counter now tracks its own value
public void Increment()
{
count++;
}
}
Resources
Documentation
Articles & blog posts
Standards
- STIG Viewer - Application Security and Development: V-222567 - The application must not be vulnerable to race conditions.