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 protected internal property in C# is a class member whose access level is a logical OR combination of the protected and internal access modifiers. It is accessible to any code within the same assembly, as well as to any derived class, regardless of whether that derived class resides in the same assembly or a different one.

Syntax

The modifier is applied directly to the property declaration. The order of the keywords protected and internal does not matter, though protected internal is the standard convention.
public class BaseClass
{
    protected internal string ConfigurationState { get; set; }
}

Accessibility Rules

The compiler evaluates access to a protected internal property based on two distinct boundaries: the assembly boundary and the inheritance hierarchy.
  1. Within the Same Assembly (internal behavior): Any type (class, struct, etc.) within the same compiled assembly can access the property, regardless of whether it inherits from the declaring class.
  2. Outside the Assembly (protected behavior): A type in a different assembly can only access the property if it explicitly derives from the declaring class.

Cross-Assembly Instance Restriction

When accessing a protected internal property from a derived class in a different assembly, the access must occur through an instance of the derived class type (or a type derived from it). You cannot access the property through an instance typed as the base class.

Code Visualization

The following example demonstrates the compiler’s behavior across two different assemblies. Assembly A
public class CoreSystem
{
    protected internal int SystemThreshold { get; set; }
}

public class SiblingComponent
{
    public void ModifyThreshold(CoreSystem system)
    {
        // Valid: Accessed within the same assembly (Internal rule applies)
        system.SystemThreshold = 100; 
    }
}
Assembly B (References Assembly A)
public class ExtensionSystem : CoreSystem
{
    public void UpdateThreshold()
    {
        // Valid: Accessed from a derived class (Protected rule applies)
        this.SystemThreshold = 200; 

        CoreSystem baseInstance = new CoreSystem();
        // INVALID: Compiler Error CS1540. 
        // Cannot access protected member via a qualifier of type 'CoreSystem'.
        // baseInstance.SystemThreshold = 300; 
    }
}

public class UnrelatedSystem
{
    public void AttemptModification(CoreSystem system)
    {
        // INVALID: Compiler Error CS0122.
        // Inaccessible due to its protection level (Not internal, not protected).
        // system.SystemThreshold = 400; 
    }
}

Technical Distinction: protected internal vs. private protected

It is critical to distinguish protected internal from private protected, as they represent opposite logical operations:
  • protected internal (Logical OR): Accessible if the caller is in the same assembly OR is a derived class. It expands accessibility.
  • private protected (Logical AND): Accessible only if the caller is in the same assembly AND is a derived class. It restricts accessibility.
Master C# with Deep Grasping Methodology!Learn More