c# – Internal and external interfaces and collections – Education Career Blog

What would be the best way to implement the following?

I have a collection of objects that implement an interface, internally I want to be able to expose set and get on the properties and externally only get.

Here’s an example of the sort of thing I want…
That does’t compile.

public interface ITable
{
   string Name { get; }
}

internal interface IInternalTable 
{
   string Name { get; set; }
}

internal class Table : ITable, IInternalTable
{
   public string Name { get; set; }
   public string ITable.Name { get { return Name; } }
}

public class Database
{
    private List<IInternalTable> tables;

    public List<ITable>
    {
       get { return this.tables; }
    }
}

,

Use this:

public interface ITable
{
    string Name { get; }
}

public class Table : ITable
{
    public string Name { get; internal set; }
}

public class Database
{
    public List<ITable> Tables { get; private set; }
}

Note: The accessibility modifier used on a get or set accessor can only restrict visibility not increase it.

,

If Table implements IInternalTable implicitly, and IInternalTable is internal, then those methods will only be accessible internally (because only internal code will be able to use IInternalTable:

public interface ITable
{
   string Name { get; }
}

internal interface IInternalTable 
{
   string Name { get; set; }
}

public class Table : ITable, IInternalTable
{
   public string Name { get; set; }
   string ITable.Name { get { return Name; } }
}

public class Database
{
    private List<Table> tables;

    public List<Table> Tables
    {
       get { return this.tables; }
    }
}

(Also now exposing Table type to avoid issues with lack of covariance… which could also be solved by Database.Tables returning a copy and having a different internal only property.)

,

It won’t compile because there is no conversion between IInternalTable and ITable. Solution is like Koistya Navin suggested:

public class Table {
    public string Name {get; internal set; }
}

public class Database {
    public IList<Table> Tables { get; private set;}

    public Database(){
        this.Tables = new List<Table>();
    }
}

,

This is a common need found in classes representing your domain model, where you want your objects to have a publicly exposed read-only property for the ID, which must be setted internally. A solution I’ve used in the past is to use a method as a setter:

public interface ITable
{
    string Name { get; }
}

internal interface ITableInternal
{
   void SetName(string value);
}

public class Table : ITable, ITableInternal
{
    public string Name { get; }

    public void SetName(string value)
    {
       // Input validation

       this.Name = value;
    }
}

public class Database
{
    public Table CreateTable()
    {
        Table instance = new Table();
        ((ITableInternal)instance).SetName("tableName");

        return table;
    }    
}

,

Actually, I’d recommend hiding the setter-interface entirely as a private interface:

public interface ITable
{
   string Name { get; }
}

public class Database
{

    private interface IInternalTable 
    {
       string Name { get; set; }
    }

    private class Table : ITable, IInternalTable
    {
        public string Name { get; set; }
        string ITable.Name { get { return Name; } }
    }

    private List<IInternalTable> tables;

    public List<ITable> Tables
    {
       get { return this.tables; }
    }
}

That way, nobody other than Database can modify the items in Database.Tables.

Leave a Comment