1

我正在为金融建模编写一个类库。

我想使用接口定义模型以创建用于测试的抽象,并在以后可能添加新的具体类。

我正在为如何定义事物列表而苦苦挣扎,所以我以后可以在具体类中添加到这些列表中。

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

IEnumerable 费用 {get; 放;}

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

我不能将列表转换为 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 功能而不是重新发明轮子。

4

2 回答 2

2

这取决于你真正想要做什么。不建议使用Listor属性,因为您可以在拥有类不知道的情况下使用它做任何事情(例如 等)。这不利于封装。您将无法在更改时执行某些操作(例如设置脏标志、触发更改的事件或进行验证)。IListClearAdd

IEnumerable是一个不错的选择。

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

// example implementation with a setter
private List<IExpense> expenses 

public IEnumerable<IExpense> Expenses 
{ 
  get { return expenses; }
  set { expenses = value.ToList(); }
}

或者,您可以实现自己的Add、或等方法。但是,如果主要用例是一次性设置所有项目,则只能有一个方法,这与我之前展示的属性上的 setter 相同。您可以考虑将其保留为内部数组。AddRangeRemoveClearSetExpenses

于 2016-09-12T18:22:01.660 回答
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,公开列表会破坏封装,通常应该避免。

于 2016-09-12T18:24:05.110 回答