有关C#中自定义集合的问题

时间:2009-08-03 13:18:52

标签: c# design-patterns

我想知道从自定义集合类返回对象时最好的模式是什么。为了说明我的问题,这是一个例子:

我有一个Customer类:

public class Customer
{
   //properties
   //methods
}

然后我有一个客户集合类:

public class Customercollection: Collection<Customer>
{

  public Collection<Customer> FindCustomers()
   {
     //calls DAL and gets a Collection of customers
     Collection<Customer> customers = DAL.GetCustomers();

     return customers;
   }
}

现在,此方法的替代版本可以是:

public class Customercollection: Collection<Customer>
{

  public Collection<Customer> FindCustomers()
   {
     //calls DAL and gets a Collection of customers
     Collection<Customer> customers = DAL.GetCustomers();
     foreach(Customer c in customers)
     this.Add(c);
     return this;
   }
}

我想讨论哪种方法更好?还有其他方法比两个以上的方法更好吗?

8 个答案:

答案 0 :(得分:15)

我会提出第三种方法:

修改 我已更新此代码示例,以反映以下OP的评论。

public class Customer
{
    public static ICollection<Customer> FindCustomers()
    {
        Collection<Customer> customers = new Collection<Customer>();

        foreach (CustomerDTO dto in DAL.GetCustomers())
            customers.Add(new Customer(dto));  // Do what you need to to create the customer

        return customers;
    }
}

大多数情况下不需要自定义集合 - 我假设这是其中一种情况。您还可以将实用程序方法添加到类型(在本例中为Customer类型),因为这有助于开发人员发现这些方法。 (这一点更多的是品味问题 - 因为这是一种静态方法,你可以自由地将它放在你想要的任何类型CustomerUtilityCustomerHelper中。)

我的最后建议是从FindCustomers()返回一个接口类型,以便将来为实现更改提供更大的灵活性。显然DAL.GetCustomers()必须返回一些实现IList<T>的类型,但是任何API方法(特别是在数据层之类的不同层)也应该返回接口类型。

答案 1 :(得分:3)

在我看来,他们两个都有点奇怪和混乱。当你扩展Collection类时,你有点暗示你的类是一个集合 - 所以它包含数据。我认为当你在第一种情况下使这个方法变为静态时,它将是最有意义的:

public class Customercollection: Collection<Customer>
{

  public static Collection<Customer> FindCustomers()
   {
     //calls DAL and gets a Collection of customers
     Collection<Customer> customers = DAL.GetCustomers();

     return customers;
   }
}

答案 2 :(得分:2)

如果您真的想在CustomerCollection类上使用这些方法,那么我建议

public static ICollection<Customer> GetAllCustomers()

public void FillWithAllCustomers()

但是,我认为您的CustomerCollection类是多余的,如果消费者想要获取客户对象的集合,他们可以直接转到DAL。

答案 3 :(得分:1)

另一种方式是:

public class Customercollection: Collection<Customer>
{
}

public class Customer
{
    public static CustomerCollection FindCustomers()
    {
        return DAL.GetCustomers();
    }
}

答案 4 :(得分:1)

我会将FindCustomers方法放在DAL类中,或者创建一个Finder类来保存该方法。有可能你以后需要更多的查找方法。

答案 5 :(得分:0)

您在第一个示例中扩展了Collection,但您从不使用Customercollection来存储任何客户。而是返回一个Collection&lt; Customer&gt;。我的建议是:

public static class Customers
{

  public static Collection<Customer> FindCustomers()
   {
     //calls DAL and gets a Collection of customers
     Collection<Customer> customers = DAL.GetCustomers();

     return customers;
   }
}

像这样使用:

Collection<Customer> customers = Customers.FindCustomers();

你的第二个例子也有点奇怪,因为如果你两次调用FindCustomers,你会在列表中给每个客户两次。

答案 6 :(得分:0)

如果你这样做会怎么样:

public class CustomerCollection: Collection<Customer>
{
  public CustomerCollection: : base(new List<Customer>())
   {}

  public static IList<Customer> FindCustomers()
  {
   //return them from DAL
  }
}

在构造函数中使用List将允许您在类中使用List中的有用方法,而无需编写自己的实现。

答案 7 :(得分:0)

我将此扩展方法添加到Andrew的建议中:

public static Collection<T> ToCollection(this IEnumerable<T> seq) {
    return new Collection<T>(seq.ToList());
}

并像这样使用它:

public static Collection<Customer> FindCustomers() { 
    return DAL.GetCustomers().Select(dto => new Customer(dto)).ToCollection();
}

或者如果你按照Andrew关于返回接口类型的建议去做,

public static IList<Customer> FindCustomers() { // or ICollection
    return DAL.GetCustomers().Select(dto => new Customer(dto)).ToList();
}