> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C# Static Property

A static property in C# is a property declared with the `static` modifier, binding it to the type itself rather than to any specific instance of that type. Consequently, a static property shares a single state across all instances of a class or struct, and it is accessed directly through the type name rather than through an object reference.

```csharp theme={"dark"}
public class ServerConfig
{
    // Auto-implemented static property with an initializer
    public static int MaxConnections { get; set; } = 100;

    // Static backing field
    private static string _environmentName;

    // Static property with explicit accessors
    public static string EnvironmentName
    {
        get => _environmentName;
        set => _environmentName = value;
    }
}

public class Program
{
    public static void Main()
    {
        // Accessing static properties (invoked on the Type, not an instance)
        ServerConfig.MaxConnections = 250;
        string currentEnv = ServerConfig.EnvironmentName;
    }
}
```

## Technical Characteristics

**Instance Independence**
Because static properties do not belong to an object instance, the `this` keyword is invalid within their `get` or `set` accessors. Furthermore, a static property cannot directly access non-static (instance) fields, methods, or properties of its containing type. It can only interact with other static members.

**Static Classes**
Static properties are a foundational component of `static` classes. When a class is declared with the `static` modifier, it cannot be instantiated, and the C# compiler enforces that all of its members—including properties, fields, and methods—must be explicitly declared as `static`.

**Initialization and Static Constructors**
While static properties can be initialized inline, complex initialization logic, exception handling, or multi-step setup requires a static constructor (`static ClassName()`). The Common Language Runtime (CLR) guarantees that the static constructor executes in a thread-safe manner exactly once per type before any static members are accessed or any instances are created.

```csharp theme={"dark"}
public class DatabaseConfig
{
    public static string ConnectionString { get; }

    // Static constructor
    static DatabaseConfig()
    {
        // Complex initialization logic
        ConnectionString = "Server=myServer;Database=myDataBase;";
    }
}
```

**Behavior in Generic Classes**
When a static property is declared within a generic class, instances of that generic class share the static state only if they share the exact same type arguments. The C# compiler and CLR generate a completely independent static state and backing field for each *closed constructed type*.

```csharp theme={"dark"}
using System;

public class StateContainer<T>
{
    public static int InitializationCount { get; set; }
}

public class Program
{
    public static void Main()
    {
        StateContainer<int>.InitializationCount = 5;
        StateContainer<string>.InitializationCount = 10;
        
        // Output is 5. The <int> and <string> types maintain isolated static states.
        Console.WriteLine(StateContainer<int>.InitializationCount); 
    }
}
```

**Memory Allocation and Lifecycle**
The compiler generates a static backing field for auto-implemented static properties. The CLR allocates memory for these static fields in the High Frequency Heap when the type is first loaded into the Application Domain (or `AssemblyLoadContext` in modern .NET). This memory remains allocated for the lifetime of the application domain, meaning the state persists globally until the application terminates or the context is unloaded.

**Polymorphism and Inheritance**
In classes and structs, static properties are resolved at compile-time (early binding) and cannot be marked as `virtual`, `abstract`, or `override`. A derived class hides a base class's static property by declaring a static property with the same name (member shadowing). This shadowing occurs even if the `new` keyword is omitted, though omitting it generates a compiler warning (`CS0108`). Explicitly using the `new` keyword suppresses this warning.

Starting with C# 11, interfaces can declare `static abstract` and `static virtual` properties. This feature explicitly enables static polymorphism over types, allowing generic constraints to enforce that a type implements specific static properties.

```csharp theme={"dark"}
public interface IConfigurable
{
    // C# 11 static abstract property in an interface
    static abstract string DefaultConfig { get; }
}

public class AppConfig : IConfigurable
{
    // Implementation of the static abstract property
    public static string DefaultConfig => "appsettings.json";
}

public class BaseClass
{
    public static string Status { get; set; } = "Base";
}

public class DerivedClass : BaseClass
{
    // Hides the static property of the base class, suppressing CS0108
    public static new string Status { get; set; } = "Derived";
}
```

**Thread Safety and Synchronization**
By default, static properties are not thread-safe. Because they represent shared global state, concurrent read/write operations from multiple threads can result in race conditions or data corruption. If a static property is mutable and shared across threads, explicit synchronization is required.

When using the `lock` statement to synchronize access, developers must use a dedicated reference type synchronization object. Attempting to lock a value type backing field results in a compiler error (`CS0185`).

To maintain thread-isolated static properties without the overhead of locking, developers use thread-local storage. This is achieved by applying the `[ThreadStatic]` attribute to a static backing field or by using the `ThreadLocal<T>` type, which ensures each thread maintains its own independent state for that static property.

```csharp theme={"dark"}
using System.Threading;

public class ThreadSafeConfig
{
    private static int _activeConnections;
    private static readonly object _lockObj = new object();

    // Synchronized shared static property
    public static int ActiveConnections
    {
        get
        {
            lock (_lockObj) { return _activeConnections; }
        }
        set
        {
            lock (_lockObj) { _activeConnections = value; }
        }
    }

    // Thread-isolated static property
    private static readonly ThreadLocal<string> _transactionId = new ThreadLocal<string>();

    public static string TransactionId
    {
        get => _transactionId.Value;
        set => _transactionId.Value = value;
    }
}
```

**Access Modifiers**
The `static` modifier dictates *binding*, not *visibility*. Static properties can be assigned any standard access modifier (`public`, `private`, `protected`, `internal`, etc.). A `private static` property is only accessible to other members (static or instance) within the same class.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C# Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
