在课堂上有一个集合

时间:2014-01-20 23:11:42

标签: c# collections

当一个类必须有某种对象的容器(集合)时,有几种选择,我想知道我更喜欢哪种实现。

以下是我找到的选项:

public class AClass : IEnumerable<string>{
   private List<string> values = new List<string>()

   IEnumerator IEnumerable.GetEnumerator()
   {
      return GetEnumerator();
   }

   public IEnumerator<T> GetEnumerator(){
      return values.GetEnumerator();
   }
}

优点:AClass不依赖于集合的具体实现(在本例中为List)。

缺点:AClass没有添加和删除元素的接口

public class AClass : ICollection<string>{
   private List<string> values = new List<string>()

   IEnumerator IEnumerable.GetEnumerator()
   {
      return GetEnumerator();
   }

   public IEnumerator<T> GetEnumerator(){
      return values.GetEnumerator();
   }

   //other ICollectionMembers
}

优点:与IEnumerable相同,并且具有添加和删除元素的界面

缺点:ICollection接口定义了很少使用的其他方法,仅仅为了接口而实现这些方法很无聊。 IEnumerable LINQ扩展还负责其中一些。

public class AClass : List<string>{

}

优点:无需实施任何方法。调用者可以调用List

实现的任何方法

缺点:AClass依赖于集合List,如果它发生变化,则可能需要更改某些调用者代码。此外,AClass不能继承任何其他类。

问题是:我更喜欢说哪一个我的类包含支持添加和删除操作的集合?或其他建议......

4 个答案:

答案 0 :(得分:4)

我的建议是在您的类中定义一个通用List,并编写其他AddRemove方法,并实现IEnumerable:

public class MyClass : IEnumerable
{
    private List<string> myList;

    public MyClass()
    {
        myList = new List<string>();
    }

    public void Add(string item)
    {
        if (item != null) myList.Add(item);
    }

    public void Remove(string item)
    {
        if (myList.IndexOf(item) > 0) myList.Remove(item);
    }

    public IEnumerable<string> MyList { get { return myList; } }

    public IEnumerator GetEnumerator()
    {
        return myList.GetEnumerator();
    }
}

如果您不想实现自己的集合,这是最好的方法。您不需要实现AddRemove方法的接口。这样的其他方法适合您的需要我猜。

答案 1 :(得分:1)

这实际上是一个基于意见的问题,并不具体用于SO。但是,如您所列,所有实现都有不同的专业版和版本,实际上您实现的是最适合应用程序使用的选项。

在我的个人观点中,我会选择第一个选项,并添加与内部集合接口所需的方法。这很容易实现并且易于使用。

类似的东西。

public class AClass : IEnumerable<string>
{
    public AClass()
    {
        this.values = new List<string>();
    }

    private readonly List<string> values;

    public void Add(string inputString)
    {
        this.values.Add(inputString);
    }

    public void Remove(string inputString)
    {
        this.values.Remove(inputString);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public IEnumerator<string> GetEnumerator()
    {
        return values.GetEnumerator();
    }
}

现在这里有简单的添加\删除功能。另请注意,我使用了readonly列表,因为列表在调用构造函数后不需要休息。

根据评论更新AS。

是的,您确实已经从列表转换为AClass其他类(无论如何都必须)。我添加了一个额外的构造函数和一个隐式运算符,用于从构造函数中的List或IEnumerable进行强制转换。

public class AClass : IEnumerable<string>
{
    public static implicit operator AClass(List<string> collection)
    {
        return new AClass(collection);
    }

    public static implicit operator List<string>(AClass aClass)
    {
        return aClass.values;
    }

    public AClass()
    {
        this.values = new List<string>();
    }

    public AClass(IEnumerable<string> collection)
    {
        this.values = collection.ToList();
    }

    private readonly List<string> values;

    public void Add(string inputString)
    {
        this.values.Add(inputString);
    }

    public void Remove(string inputString)
    {
        this.values.Remove(inputString);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public IEnumerator<string> GetEnumerator()
    {
        return values.GetEnumerator();
    }
}

然后可以使用以下方式:

List<string> listA = new List<string>();

AClass classA = new AClass(); //parameterless constructor
AClass classA1 = new AClass(listA); //simple constructor call with collection
AClass classA2 = (AClass)listA; //direct cast
List<string> listB = (List<string>)listA; //cast back to a list

只是一个想法,仍然是个人意见

答案 2 :(得分:0)

这只是塞尔曼建议的一个小改编,所以他的回答符合我的期望:

public class MyClass : IEnumerable<string>
{
   private List<string> myList;

   public MyClass()
   {
       myList = new List<string>();
   }

   public ICollection<string> MyList { get { return myList; } }

   IEnumerator IEnumerable.GetEnumerator()
   {
      return GetEnumerator();
   }

   public IEnumerator<T> GetEnumerator(){
      return myList.GetEnumerator();
   }
}

答案 3 :(得分:0)

我喜欢你解释思路的方式。

您已找到3种完美的商品解决方法。你的利弊让我觉得你理解正确。

没有银弹可以解决所有问题。但是你最好有一个软件架构师工具箱包含设计模式和一些常识。

下次遇到挑战时,请使用最佳工具!