我有一个识别页面坐标的函数,我将它们作为
返回Dictionary<int, Collection<Rectangle>> GetDocumentCoordinates(int DocumentId)
但是,稍后我需要有关每个页面的信息 - 如果它已经过验证,页面分辨率是什么,颜色/ bw等等。我可以创建另一个函数并运行与前一个函数完全相同的结果集并得到那些信息。
Dictionary<int, PageInfo> GetDocumentAttributes(int DocumentId)
另一种选择是添加ref
参数,以便我可以恢复这些值。
Dictionary<int, Collection<Rectangle>> GetCoordinates(int DocumentId, ref Dictionary<int, PageInfo> PageAttributes)
另一种方法是创建一个包含字典和页面信息的包含类:
class DocumentInfo
{
Dictionary<int, Collection<Rectangle>> Coordinates { get; set;}
Dictionary<int, PageInfo> PageAttributes { get; set; }
}
然后定义:
DocumentInfo GetDocumentInfo(int DocumentId);
我倾向于最后一个选项,但非常感谢您的见解。
答案 0 :(得分:6)
最后一个选项绝对是最好的。我发现,在获取或返回具有多种含义的复杂数据时,创建一个复杂类型来封装这些数据是出于多种原因的最佳实践。
首先,您的返回数据可能会随着设计的变化而变化。将此数据封装在对象中允许您更改其携带的内容以及方法如何对此数据进行操作,而无需更改对象的 interfaces 。显然,您的数据对象不应该实现接口;最多,有一个具有最小接口的基类,然后将引用传递给基础。
其次,您可能会发现您的数据变得复杂到需要对其进行验证的程度。您可以轻松地将其包含在数据类中,而不是在您处理此数据的类的所有方法中进行此验证。单一责任等。
答案 1 :(得分:1)
好像你需要大量数据。最后一个选项应该没问题,并且是可扩展的;你想要它(为了简化Dictionary<,>
用法),你可以将事情封装得更多,但是C#不直接支持命名索引属性的事实意味着你需要一些类,除非你只是用方法如:
class DocumentInfo {
Dictionary<int, Collection<Rectangle>> rectangles = ...
public Collection<Rectangle> GetRectangles(int index) {
return rectangles[index]; // might want to clone to
// protect against mutation
}
Dictionary<int, PageInfo> pages = ...
public PageInfo GetPageInfo(int index) {
return pages[index];
}
}
我不太清楚int
是什么,所以我不能说这是否合情合理(所以我只是把它放在一边)。
另外 - 使用第一个选项,您可能不需要ref
- 使用out
就足够了。