如何将一系列项添加到IList变量

moh*_*sti 64 c# collections list addrange

没有AddRange()办法IList<T>.

如何在IList<T>不迭代项目和使用Add()方法的情况下将项目列表添加到a ?

Bla*_*ack 56

如果你查看Listc#源代码,我认为List.AddRange()具有简单循环无法解决的优化.因此,扩展方法应该只检查IList是否为List,如果是,则使用其原生AddRange().

在源代码中,您会看到.NET伙伴在他们自己的Linq扩展中执行类似的事情,例如.ToList()(如果它是一个列表,则抛出它...否则创建它).

public static class IListExtension
{
    public static void AddRange<T>(this IList<T> list, IEnumerable<T> items)
    {
        if (list == null) throw new ArgumentNullException("list");
        if (items == null) throw new ArgumentNullException("items");

        if (list is List<T>)
        {
            ((List<T>)list).AddRange(items);
        }
        else
        {
            foreach (var item in items)
            {
                list.Add(item);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 从优化的角度来看,你实际上在这里两次将`list`转换为`List <T>`.其中一个可以使用`as`关键字进行优化. (3认同)
  • @zuckerthoben - 我刚刚使用两种方法进行了一次迭代100万次迭代测试,性能没有差异.所以我不会称之为优化...另外,它增加了一行代码(但减少了一个parens强制转换).无论如何,我现在可能会使用'as':var listCasted = list作为List <T>; if(listCasted!= null){listCasted.AddRange(items);}.不值得更新答案恕我直言,但很好介绍作为一种语法替代. (2认同)
  • 截至目前,您可以执行 `if (list is List&lt;T&gt; castedList) { castedList.AddRange(items); }` (2认同)

Ode*_*ded 55

AddRange是定义List<T>,而不是接口.

您可以将变量声明为List<T>代替IList<T>或转换List<T>为以获取访问权限AddRange.

((List<myType>)myIList).AddRange(anotherList);
Run Code Online (Sandbox Code Playgroud)

  • 不不不.这是一个IList <T>的原因是因为它可能不是List <T>实现.如果你真的需要一个AddRange方法,写一个BlackjacketMack所示的扩展方法. (39认同)
  • 不知道为什么会收到这么多的upvotes,因为如果在`List <T>`(例如数组)以外的任何东西上使用它会明显抛出像InvalidCastException这样的东西. (5认同)
  • 但是,施法并不是一个好主意.它可能导致性能开销. (3认同)
  • @ mohsen.d-如果生成了类型,则您不想更改生成的代码(因为它可能会被覆盖)。强制转换或使用LINQ`Concat`,作为@Self_Taught_Programmer [已回答](http://stackoverflow.com/a/13158155/1583)。 (2认同)
  • @ mohsen.d-如果是您的代码,则可以将类型声明为`List &lt;T&gt;`(或者,如果这不是您的好选择,请在需要添加`AddRange`的地方进行强制转换本地化-这是一项非常低成本的操作)。 (2认同)

Ray*_*awn 20

你可以这样做:

IList<string> oIList1 = new List<string>{"1","2","3"};
IList<string> oIList2 = new List<string>{"4","5","6"};
IList<string> oIList3 = oIList1.Concat(oIList2).ToList();
Run Code Online (Sandbox Code Playgroud)

资源

所以,基本上你会使用concat扩展和ToList()来获得与AddRange()类似的功能.

  • 你的方法的问题是 `Enumerable.Concat` 是由 `System.Linq.Enumerable` 实现的,并且该方法的返回值是 `IEnumerable&lt;TSource&gt;`,所以我认为它不应该被转换回 `IList&lt;TSource &gt;` - 由于我们不检查源代码的情况下不知道的实现细节,它可能会返回其他内容 - 即使不能保证它不会改变 - 因此在支持多个 .NET 版本时必须特别注意。 (2认同)

bas*_*his 7

您还可以编写这样的扩展方法:

internal static class EnumerableHelpers
{
    public static void AddRange<T>(this IList<T> collection, IEnumerable<T> items)
    {
        foreach (var item in items)
        {
            collection.Add(item);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

        IList<int> collection = new int[10]; //Or any other IList
        var items = new[] {1, 4, 5, 6, 7};
        collection.AddRange(items);
Run Code Online (Sandbox Code Playgroud)

它仍在迭代项目,但您不必在每次调用时编写迭代或转换.