4

示例:我想要一个自定义集合类的Add方法ICollection来实现方法链接和流利的语言,所以我可以这样做:

randomObject.Add("I").Add("Can").Add("Chain").Add("This").

我可以想到一些选项,但它们很混乱,并且涉及将 ICollection 包装在另一个界面中等等。

4

6 回答 6

11

虽然流利很好,但我更感兴趣的是添加一个AddRange(或两个):

public static void AddRange<T>(this ICollection<T> collection,
    params T[] items)
{
    if(collection == null) throw new ArgumentNullException("collection");
    if(items == null) throw new ArgumentNullException("items");
    for(int i = 0 ; i < items.Length; i++) {
        collection.Add(items[i]);
    }
}
public static void AddRange<T>(this ICollection<T> collection,
    IEnumerable<T> items)
{
    if (collection == null) throw new ArgumentNullException("collection");
    if (items == null) throw new ArgumentNullException("items");
    foreach(T item in items) {
        collection.Add(item);
    }
}

params T[]方法允许AddRange(1,2,3,4,5)等,并且IEnumerable<T>允许与 LINQ 查询之类的东西一起使用。

如果您想使用流畅的 API,您还可以Append在 C# 3.0 中编写为扩展方法,通过适当使用通用约束来保留原始列表类型:

    public static TList Append<TList, TValue>(
        this TList list, TValue item) where TList : ICollection<TValue>
    {
        if(list == null) throw new ArgumentNullException("list");
        list.Add(item);
        return list;
    }
    ...
    List<int> list = new List<int>().Append(1).Append(2).Append(3);

(注意它返回List<int>

于 2009-08-29T07:41:36.313 回答
5

You could also use an extension method that would be usable with any ICollection<T> and save you from writing your own collection class:

public static ICollection<T> ChainAdd<T>(this ICollection<T> collection, T item)
{
  collection.Add(item);
  return collection;
}
于 2009-08-28T22:51:35.663 回答
3

You would need to return void from Add as that is how it is set out in ICollection. That rules out the chained Add Method taking just one parameter, I believe.

Not quite what you want but you could add something like this to your custom collection type.

public CustomCollectionType Append(string toAdd)
{
  this.Add(string toAdd);
  return this;
}

Then you could do:

customCollection.Append("This").Append("Does").Append("Chain");

Hope that helps,

Dan

于 2009-08-28T22:42:12.157 回答
2

Another option would be to use the C# collection initializer:

var list = new YourList<String>()
    {
         "Hello",
         "World",
         "etc..."
    };
于 2009-08-28T22:49:20.113 回答
0

You can hide ICollection.Add method in your custom collection class and return this.

public class MyList<T>:List<T>
{
  public new MyList<T> Add(T item)
  {
     (this as ICollection<T>).Add(item);
     return this;
  }
}

then you can add item with chained Add calls:

MyList<string> strList = new MyList<string>();
strList.Add("Hello").Add(" ").Add("World!");
于 2009-08-28T22:47:02.957 回答
0

无意冒犯,但也许您更喜欢 VB.NET

它比 C# 更有利于“自然语言”编程。

在 VB.NET 中,您可以使用“with”构造来执行以下操作:

With myCollection
    .Add("Hello")
    .Add("There")
    .Add("My")
    .Add("Name")
    .Add("Is")
    .Add("Silky")
    .Sort()
End With
于 2009-08-29T08:08:54.420 回答