Search code examples
c#inner-classesreadonly

Inner class property make read only to all accessing classes except outer class


I am new to C# and while coding I stumbled on this. I'm unsure how to word it, so I'll share the code first (it is dummy code just to explain my question).

public class DatabaseConnector
{
   public Caching Cache { get; set; }
   //More properties
   //some methods
   public DatabaseConnector(string[] parameters)
   {
      Connect(parameters);
   }
   protected void Connect(string[] parameters) 
   {
         Cache = new Caching();
         Cache.Enabled = true; //this value is set depending on parameters and the database condition.
         //Irrelevant Code 
   }
    
   //Method to get the database
   
   public class Caching
   {
      public bool Enabled { get; set; }
      //other properties
      public Caching()
      {
          this.Enabled = false;
          //other properties 
      }
   }
}

Now When user uses the class as

DatabaseConnector dbConnector = new DatabaseConnector(arguments);
 
dbConnector.Cache.Enabled = false; //Should throw error     

if(dbConnector.Cache.Enabled) //should work.
    dbConnector.Executesomemethod();
else
   dbConnector.ExecutesomeOthermethod();

I want to make the inner class Caching Enabled property as the read only to the all classes except the Outer class. Currently what I am doing is in each Executesomemethod(), ExecutesomeOthermethod(),....,n I am checking the conditions which are already checked in the constructor/connect method to set the Enabled value.

What I want is a way to make the inner class property read only to all accessing classes except the Outer class.


Solution

  • There's no way of doing that - other than the visibility of the class itself, outer classes have no extra access to the members within a nested class.

    Two options:

    • Keep a cachingEnabled private field within DatabaseConnector instead, and give Cache an instance of the DatabaseConnector to fetch it from. (It can read private fields, as it's a nested class.)
    • Separate the read-only part from the writable part:

      public interface ICache
      {
          bool Enabled { get; }
      }
      
      public class DatabaseConnector
      {
          private Cache cache;
          public ICache Cache { get { return cache; } }
      
          ...
      
          private class Cache
          {
              // Implementation with writable property
              public bool Enabled { get; set; }
          }
      }
      

    Note that because the implementation is a private nested class, callers can't even cast the result of the Cache property and call the setter that way. (They could use reflection, in a full-trust environment, of course.)