有没有一个不错的简单&让 ICollection 在 C# 中更加流畅的优雅方法?

发布于 2024-08-03 05:23:13 字数 234 浏览 10 评论 0原文

示例:我想要自定义集合类的 ICollectionAdd 方法来实现方法链接和流畅的语言,这样我就可以做到这一点:

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

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

Example: I would like to have the Add method of ICollection of a custom collection class to implement method chaining and fluent languages so I can do this:

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

I can think of a few options but they are messy and involves wrapping ICollection in another interface and so forth.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

初吻给了烟 2024-08-10 05:23:13

虽然流畅性很好,但我更感兴趣的是添加一个 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 允许与 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

While fluent is nice, I'd be more interested in adding an AddRange (or two):

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);
    }
}

The params T[] approach allows AddRange(1,2,3,4,5) etc, and the IEnumerable<T> allows use with things like LINQ queries.

If you want to use a fluent API, you can also write Append as an extension method in C# 3.0 that preserves the original list type, by appropriate use of generic constraints:

    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);

(note it returns List<int>)

月棠 2024-08-10 05:23:13

您还可以使用可与任何 ICollection 一起使用的扩展方法,这样您就无需编写自己的集合类:

public static ICollection<T> ChainAdd<T>(this ICollection<T> collection, T item)
{
  collection.Add(item);
  return collection;
}

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;
}
神也荒唐 2024-08-10 05:23:13

您需要从 Add 返回 void,因为这就是 ICollection 中的设置方式。我相信,这排除了仅采用一个参数的链式添加方法。

不完全是您想要的,但您可以将类似的内容添加到您的自定义集合类型中。

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

那么你可以这样做:

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

希望有帮助,

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

苍暮颜 2024-08-10 05:23:13

另一种选择是使用 C# 集合初始值设定项:

var list = new YourList<String>()
    {
         "Hello",
         "World",
         "etc..."
    };

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

var list = new YourList<String>()
    {
         "Hello",
         "World",
         "etc..."
    };
美羊羊 2024-08-10 05:23:13

您可以在自定义集合类中隐藏 ICollection.Add 方法并返回该方法。

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

然后您可以使用链式 Add 调用添加项目:

MyList<string> strList = new MyList<string>();
strList.Add("Hello").Add(" ").Add("World!");

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!");
温暖的光 2024-08-10 05:23:13

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

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

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

With myCollection
    .Add("Hello")
    .Add("There")
    .Add("My")
    .Add("Name")
    .Add("Is")
    .Add("Silky")
    .Sort()
End With

No offense, but maybe you would prefer VB.NET

It's more conducive to 'natural language' programming than C# is.

In VB.NET you have the "with" construct that will let you do:

With myCollection
    .Add("Hello")
    .Add("There")
    .Add("My")
    .Add("Name")
    .Add("Is")
    .Add("Silky")
    .Sort()
End With
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文