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
.