有没有人知道为.NET 3.0或更高版本创建组件的分层对象模型的好教程(C#首选),即充分利用泛型?
string columnName = db.Tables["Customers"].Columns["customer_number"].Name;
我发现这篇文章Component Object-Model Recommendations,但因为它适用于Visual Studio .NET 2003,但我认为.NET 3.0中有更好的方法。
感谢。
更新:
如果我正确理解了索引器......
在db
类中,我可以使用SortedList
作为Table的容器,并使用和索引器来访问以返回Table
实例。同样,Table
的索引器将访问Column
实例。所以客户端代码可能如下所示:
string tableName = db["Customers"].Name;
问题是,除了db
(Tables
,StoredProcs
等)之外,DBViews
类还会公开其他集合。所以我想我想保留每个的集合类,将它们作为属性公开,而不是使用索引器。这听起来不错吗?我应该在这些集合类上使用索引器吗?
答案 0 :(得分:2)
允许客户端代码使用“隧道”样式,例如
string columnName = db.Tables["Customers"].Columns["customer_number"].Name;
[...]我想保留每个的集合类,将它们作为属性公开,而不是使用索引器。听起来不错吗?
是的,这听起来比索引器好,因为它可以提供更好的类型安全性。如果公开普通集合,则每个集合都可以拥有自己的元素类型。使用索引器,您将被迫为所有公开的集合选择相同的集合类型。为了说明这一事实:
public DataTable this[string tableName] { ... }
// ^^^^^^^^^
// choose one, unspecific type for all exposed collections
VS
public IList<Customer> Customers { get { ... } }
public IList<Supplier> Suppliers { get { ... } }
// ^^^^^^^^
// the right type for each collection
所以是的,请展示单个“类型”集合,而不是“无类型”集合集合。
旁注:您说您想允许隧道;有些人可能会告诉你,这违反了一些常用的OO原则,例如单一责任原则(SRP)或关注点分离(SoC)。
- 阻止客户端应用程序直接实例化包含的对象
public class Db
{
public IList<Customer> Customers { get { ... } }
...
}
“包含对象”在这里意味着两件事:
有人可以替换您的整个Customers
集合。您只需将属性设置为只读即可以防止这种情况发生。只提供一个吸气剂。
有人可以在您的Customer
集合中插入新的db.Customers
。您可以通过选择不允许插入的Customers
的(只读)集合类型来阻止这种情况。
例如:
private List<Customer> customers = new List<Customer>();
// ^ for class-internal use only
public IList<Customer> Customers { get { return this.customers.AsReadOnly(); } }
// ^^^^^^^^^^^^^
// expose collection as read-only
- 使用并公开无限数量的包含对象
这又可能意味着两件事:
您的db
会曝光无限数量的收藏品。显然,当您希望每个集合都是特定类型时,这将不起作用。这仅适用于将所有集合公开为具有相同类型的集合(例如DataTable
s或非通用ICollection
s),并且将需要提供索引器。也就是说,您可以通过索引器公开的一个集合访问许多集合。
您公开了众所周知且数量有限的集合(例如Customers
,Suppliers
等)。但是,其中每个都可以包含任意数量的子对象。当我写下我的答案的上述部分时,我已经假设了这种情况。当您进行隧道掘进时,优点是更好的类型安全性和编译时检查。
关于最后一点:
db.Customers["John Smith"].BillingAddress
VS
db.Tables["Customers"].Rows["John Smith"].Columns["BillingAddress"] as Address
在第一种情况下,编译器可以检查属性的类型,例如Customers
,BillingAddress
,而在第二种情况下,这些属性被编码为字符串,编译器不会注意到如果你在那里有拼写错误。此外,您必须使用type-casts自己指出正确的数据类型。
答案 1 :(得分:1)
阅读使用C#语言的索引器。这是一个relevant page。