首页 文章

在具体的类实现中IEnumerable与List

提问于
浏览
1

我正在为财务建模编写一个类库 .

我想使用接口来定义模型,以便为测试创建抽象,以及稍后可能添加新的具体类 .

我正在努力研究如何定义事物列表,所以我稍后可以在具体类中添加这些列表 .

例如,如果我将一个接口定义为在我的模型中有一个费用列表

IEnumerable Expenses {get;组;}

然后想要创建一个名为ABCModel的具体类,其中包含一个具体的XYZExpense列表,这是实现列表的最佳方法,这样我可以轻松地将更多项添加到列表中?

我不能将List强制转换为IEnumerable .

例如:

public interface IFinancialModel
{
    IEnumerable<IExpense> Expenses { get; }
    IEnumerable<IRevenue> Revenue { get; }
    IEnumerable<IAsset> Assets { get; }
    IEnumerable<ILiability> Liabilities { get; }
}

我需要一个名为public class FinancialModel的具体类:IFinancialModel

并能够添加具体项目 .

我应该创建自己的“添加”方法吗?理想情况下,我想利用内置的List功能,而不是重新发明轮子 .

2 回答

  • 1

    这取决于你真正想做的事情 . 建议不要使用 ListIList 属性,因为您可以使用它完成所有操作(如 ClearAdd 等),而无需拥有类知道它 . 这对封装不利 . 您将无法在更改时执行某些操作(例如设置脏标志,触发更改事件或执行验证) .

    IEnumerable 是个不错的选择 .

    您可以添加setter,但不应该通过引用获取为该属性设置的值 . 它可以是任何内容,例如Linq查询甚至是数据库查询,您不想引用它们 . 你只想要这些物品 . (还要考虑对来自外部的集合的引用可以分配给其他实例,这会在其中更改时导致非常糟糕的副作用,但不应在此处更改 . )

    // example implementation with a setter
    private List<IExpense> expenses 
    
    public IEnumerable<IExpense> Expenses 
    { 
      get { return expenses; }
      set { expenses = value.ToList(); }
    }
    

    或者,您可以实现自己的 AddAddRangeRemoveClear 等方法 . 但是,如果主要用例是一次性设置所有项目,则只能使用 SetExpenses 方法,该方法与我之前显示的属性上的setter相同 . 您可以考虑在内部将其保留为数组 .

  • 0

    你在找什么是 IList<T> . 这是一个界面,允许您在隐藏实际列表实现时公开列表 . 例如:

    interface IFinancialModel {
        IList<IExpense> Expenses { get; }
    }
    

    然后使用满足您需求的列表实现 . 例如:

    class FinancialModel : IFinancialModel {
        private IList<IExpense> _expenses = new List<IExpense>();
        IList<IExpense> Expenses { get { return _expenses; } }
    }
    

    我同意@Stefan,暴露一个列表打破封装,一般应该避免 .

相关问题