C# 接口过载?

C# 接口过载?,c#,oop,C#,Oop,因此,我认为我的实现可能过于复杂化了,但我现在做的是: 我希望我的数据库由IRepository表示 SQLRepository是IRepository的一个具体实现 我希望数据库中的所有表都用ITable表示 我有一个名为Items的表,它由ItemsTable表示 Items表中的每个记录都由IItem表示 项目是项目的具体实施 现在我的问题是,在我的程序中,当我想使用List items=repository.items.List()时;它不会编译,因为在ItemsTable中,ITabl

因此,我认为我的实现可能过于复杂化了,但我现在做的是:

  • 我希望我的数据库由IRepository表示
  • SQLRepository是IRepository的一个具体实现
  • 我希望数据库中的所有表都用ITable表示
  • 我有一个名为Items的表,它由ItemsTable表示
  • Items表中的每个记录都由IItem表示
  • 项目是项目的具体实施
  • 现在我的问题是,在我的程序中,当我想使用List items=repository.items.List()时;它不会编译,因为在ItemsTable中,ITable的实现返回IList而不是List。我可以返回IList,但我确实希望使用一个具体的项目列表

    我能做得更好吗

     public interface ITable
        {
            IList<IItem> List();
            bool Add(IItem item);
            bool Delete(long itemId);
            bool Find(long itemId);
        }
    
    public class ItemsTable : ITable
    {
        public IList<IItem> List()
        {
            IList<IItem> items = GetItems(); // GetItems return List<Item>, Item implements IItem.
            return items;
        }
    
       .....
       ...
       ..
    }
    
    public class SQLRepository : IRepository
    {
        ITable items = new ItemsTable();
    
        public ITable Items
        {
            get { return items; }
        }
    }
    
    
        static void Main(string[] args)
        {
            var repository = new SQLRepository();
            List<Item> items = repository.Items.List();
        }
    
    公共接口ITable
    {
    IList列表();
    bool Add(项目项);
    bool Delete(长itemId);
    bool-Find(长itemId);
    }
    公共类ItemsTable:ITable
    {
    公共IList列表()
    {
    IList items=GetItems();//GetItems返回列表,项实现IItem。
    退货项目;
    }
    .....
    ...
    ..
    }
    公共类SQLRepository:IRepository
    {
    ITable items=新的ItemsTable();
    公共物品
    {
    获取{返回项;}
    }
    }
    静态void Main(字符串[]参数)
    {
    var repository=newsqlrepository();
    List items=repository.items.List();
    }
    
    最好将您的界面更改为:

    public interface ITable<TItem>
        where TItem : IItem
    {
        IList<TItem> List();
        bool Add(TItem item);
        bool Delete(long itemId);
        bool Find(long itemId);
    }
    
    公共接口ITable
    在哪里
    {
    IList列表();
    bool Add(滴度项目);
    bool Delete(长itemId);
    bool-Find(长itemId);
    }
    
    最好将您的界面更改为:

    public interface ITable<TItem>
        where TItem : IItem
    {
        IList<TItem> List();
        bool Add(TItem item);
        bool Delete(long itemId);
        bool Find(long itemId);
    }
    
    公共接口ITable
    在哪里
    {
    IList列表();
    bool Add(滴度项目);
    bool Delete(长itemId);
    bool-Find(长itemId);
    }
    
    现在我的问题是,在我的程序中,当我想使用List items=repository.items.List()时;它不会编译,因为在ItemsTable中,ITable的实现返回IList而不是List。我可以返回IList,但我确实希望使用一个具体的项目列表

    嗯。你不能两者兼得。如果要使用
    列表
    ,需要返回一个。您不能创建一个契约,声明任何
    IList
    实现都正常,然后期望返回
    列表

    由于
    IList List(),此类违规行为通常会在将来导致维护混乱承诺一件事,你期望它能带来其他的东西。这就像是去加油站点无铅汽油,期待有铅汽油(还是汽油,但有一点led)

    现在我的问题是,在我的程序中,当我想使用List items=repository.items.List()时;它不会编译,因为在ItemsTable中,ITable的实现返回IList而不是List。我可以返回IList,但我确实希望使用一个具体的项目列表

    嗯。你不能两者兼得。如果要使用
    列表
    ,需要返回一个。您不能创建一个契约,声明任何
    IList
    实现都正常,然后期望返回
    列表


    由于
    IList List(),此类违规行为通常会在将来导致维护混乱承诺一件事,你期望它能带来其他的东西。这就像去加油站订购无铅汽油,而期望使用含铅汽油(它仍然是汽油,但有一点led)。

    在.NET中,对于一般收集,没有差异

    显式实现接口方法,并提供返回具体列表的重载:

    public MyTable : ITable
    {
       IList<IItem>ITable List()
       {
          return List().OfType<IItem>().ToList();
       }
    
    
       public List<MyItem> List()
       {
    
          var l = new List<MyItem>();
    
          ...
    
          return l;
       }
    }
    
    公共MyTable:ITable
    {
    IListable List()
    {
    返回列表().OfType().ToList();
    }
    公开名单()
    {
    var l=新列表();
    ...
    返回l;
    }
    }
    
    对于泛型集合,.NET中没有差异

    显式实现接口方法,并提供返回具体列表的重载:

    public MyTable : ITable
    {
       IList<IItem>ITable List()
       {
          return List().OfType<IItem>().ToList();
       }
    
    
       public List<MyItem> List()
       {
    
          var l = new List<MyItem>();
    
          ...
    
          return l;
       }
    }
    
    公共MyTable:ITable
    {
    IListable List()
    {
    返回列表().OfType().ToList();
    }
    公开名单()
    {
    var l=新列表();
    ...
    返回l;
    }
    }
    
    我有几点意见要给你

    首先,仅仅因为定义了映射到具体类的接口,就不需要到处使用接口。使用您正在使用的接口列表的目的是限制存储库和对象的用户可以使用的表面积。因此,请随意返回
    List
    ,而不是
    IList

    其次&然而,返回任何实现了
    IList
    的内容意味着您希望在从存储库获取列表后修改列表的内容。现在这样做可能会越来越糟糕,原因有很多

    如果您的存储库保留了对它返回的列表的引用,那么后续调用方可以获得您修改过的列表,因此您确实无法保留引用。因此,您需要为每个通话建立列表

    如果您为每次呼叫建立列表,那么在返回结果之前,您实际上是在调用
    .ToList
    操作符

    另一种方法是允许调用方决定何时调用
    .ToList
    ,然后您只需返回一个
    IEnumerable

    现在这在很多方面都更好了

    它让调用代码知道列表没有被其他调用方修改。它还允许列表为列表的每个新迭代重新查询自身


    因此,我的建议是-不要返回
    IList
    List
    -而是返回
    IEnumerable
    ,让调用者调用
    .ToList()

    ,我有几点意见给你

    首先,仅仅因为定义了映射到具体类的接口,就不需要到处使用接口。使用interface的要点