代码之家  ›  专栏  ›  技术社区  ›  Sigh

内部和外部接口和集合

  •  3
  • Sigh  · 技术社区  · 15 年前

    实现以下目标的最佳方式是什么?

    我有一个实现接口的对象集合,在内部我希望能够公开set和get属性,在外部只获取get。

    那是不可编译的。

    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; }
        }
    }
    
    5 回复  |  直到 15 年前
        1
  •  3
  •   Konstantin Tarkus    15 年前

    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; }
    }
    

    :get或set访问器上使用的辅助功能修饰符只能限制可见性,不能增加可见性。

        2
  •  1
  •   Richard    15 年前

    如果表隐式实现IIINTERNALTABLE,并且IIINTERNALTABLE是内部的,那么这些方法只能在内部访问(因为只有内部代码才能使用IIINTERNALTABLE:

    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; }
        }
    }
    

    (现在还公开了表类型,以避免缺少协方差的问题……这也可以通过数据库来解决。表返回副本并具有不同的仅内部属性。)

        3
  •  0
  •   user76035    15 年前

    它不会编译,因为IInternalTable和ITable之间没有转换。解决方案如Koistya Navin所建议:

    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>();
        }
    }
    
        4
  •  0
  •   Enrico Campidoglio    15 年前

    这是在表示域模型的类中常见的需求,您希望对象的ID具有公开的只读属性,该属性必须在内部设置。我过去使用的一种解决方案是使用方法作为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;
        }    
    }
    
        5
  •  0
  •   Shalom Craimer    15 年前

    实际上,我建议将setter接口完全隐藏为私有接口:

    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; }
        }
    }
    

    那样的话,除了我之外,没有人 Database 可以修改中的项目 Database.Tables