Skip to main content

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.

A private property in C# is a class, struct, record, or interface member that encapsulates data access using get, set, or init accessors, restricted by the private access modifier. This modifier limits accessibility strictly to the lexical scope of the declaring type. Since C# 8.0, interfaces can declare private properties to support default interface method implementations. When a property is compiled, the C# compiler generates underlying methods (e.g., get_PropertyName and set_PropertyName) corresponding to the accessors explicitly defined. For an init accessor, the compiler does not generate an init_ method; instead, it generates a standard set_PropertyName method and decorates it with a modreq (specifically System.Runtime.CompilerServices.IsExternalInit). This required modifier enforces the init-only constraint at compile time. A read-only private property will only generate a get_ method. The private access modifier restricts access to the declaring type, not the specific instance. Code executing within the declaring type can freely read or write the private properties of other instantiated objects of that exact same type. However, any attempt to access the property from an external type or a derived type will result in a compile-time error (CS0122).

Syntax Variations

Auto-Implemented Private Property The compiler automatically generates a hidden, anonymous backing field. This can utilize set or init for mutation, or omit them entirely for a get-only property.
private int InternalCounter { get; set; }
private string ImmutableState { get; init; }
Explicit Backing Field Used when custom logic is required within the accessors.
private string _internalState;

private string InternalState
{
    get { return _internalState; }
    set { _internalState = value; }
}
Expression-Bodied Private Property A concise syntax for read-only private properties, generating only a get accessor.
private double ComputedMultiplier => _baseValue * 1.5;
Interface Private Property (C# 8.0+) Interfaces can declare private properties for use exclusively within default interface methods. Because auto-implemented properties require a hidden backing field, and interfaces cannot contain instance fields, a private auto-implemented property in an interface must be marked static. If it is an instance property, it must be explicitly implemented with accessor bodies that do not rely on a backing field.
public interface IComputable
{
    // Valid: Static auto-implemented property
    private static int CachedHash { get; set; }

    // Valid: Instance property with an explicit body (no backing field)
    private int DefaultMultiplier => 2;
}

Technical Characteristics

  • Instance-to-Instance Access: Because visibility is scoped to the type, an instance of a class can access the private properties of another instance of the same class.
public class Node
{
    private int InternalId { get; set; }

    public void CopyIdFrom(Node otherNode)
    {
        // Valid: Accessing a private property of another instance of the same type
        this.InternalId = otherNode.InternalId; 
    }
}
  • Accessor Visibility: When the property itself is declared private, all defined accessors (get, set, init) are implicitly private. C# language specifications dictate that an accessor cannot have a more permissive access modifier than the property itself. Therefore, you cannot define a public get inside a private property.
  • Nested Type Access: C# access rules permit nested types to access the private members of their containing type. A class defined within the same class block as the private property can read and write to it.
  • Memory and Layout: A private property does not alter the memory layout of the object differently than a public property. The memory footprint is determined entirely by the underlying backing field.
  • Reflection Bypass: While the compiler enforces private visibility at compile-time, the property remains discoverable and accessible at runtime via the .NET Reflection API. It can be invoked using Type.GetProperty() by specifying BindingFlags.NonPublic | BindingFlags.Instance (or BindingFlags.Static for static properties).
// Accessing a private instance property via Reflection
PropertyInfo propInfo = typeof(MyClass).GetProperty("InternalCounter", BindingFlags.NonPublic | BindingFlags.Instance);
int value = (int)propInfo.GetValue(myClassInstance);
Master C# with Deep Grasping Methodology!Learn More