user2745246
user2745246

Reputation: 314

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.

Upvotes: 3

Views: 724

Answers (3)

RagtimeWilly
RagtimeWilly

Reputation: 5445

Would something like this suit your purpose:

public class DatabaseConnector
{
    public Caching Cache { get; set; }

    public DatabaseConnector(string[] paramters)
    {
        Connect(paramters);
    }

    protected void Connect(string[] paramters)
    {
        ICaching Cache = new Caching();
        Cache.Enabled = true;
    }

    private interface ICaching
    {
        bool Enabled { get; set; }
    }

    public class Caching : ICaching
    {
        private bool _enabled { get; set; }

        public Caching()
        {
            _enabled = false;
        }

        bool ICaching.Enabled
        {
            get { return _enabled; }
            set { _enabled = value; }
        }
    }
}

So the private interface will expose the properties to the outer class but anything outside this class won't be able to see the Enabled property.

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1502716

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.)

Upvotes: 4

user2930590
user2930590

Reputation:

Change the property:

public bool Enabled { get; set; }

to:

public bool Enabled { get; private set; }

Change the Cache class constructor to:

public Cache(bool enabled)
{
   Enabled = enabled;
}

Change when constructing Cache class to:

Cache = new Caching(true);
// remove this line Cache.Enabled = true; 

Upvotes: 2

Related Questions