简体   繁体   English

尝试将IList转换为List以进行AddRange

[英]Trying to convert IList to List in order to AddRange

I have a IList . 我有一个IList I try to call ToList and then AddRange . 我尝试先调用ToList然后再调用AddRange

However, the ToList() overwrite all the results. 但是, ToList()覆盖所有结果。 How come? 怎么会?

private void AddAliasesThatContainsCtid(string ctid, IList<MamConfiguration_V1> results)
{

...
    foreach (var alias in aliases)
    {
        var aliasId = "@" + alias;

    results.ToList().AddRange(mMaMDBEntities.MamConfigurationToCTIDs_V1.Where(item => item.CTID == aliasId)
                             .Select(item => item.MamConfiguration_V1)
                             .ToList());
    }

}

.ToList() does not convert an IEnumerable<T> to a List<T> , it creates and returns a new list filled with the values of the enumerable. .ToList()不会将IEnumerable<T>转换为List<T> ,而是创建并返回一个新列表,该列表填充了可枚举的值。

So your result.ToList() will create a new list and fill it with some data. 因此,您的result.ToList()将创建一个新列表并将其填充一些数据。 But it will not change the contents of the object referenced by the result parameter. 但是它不会更改result参数引用的对象的内容。

In order to actually change the contents of the result parameter you have to use the .Add method of it or if your design allows it change the type of result to List<..> . 为了实际更改result参数的内容,必须使用它的.Add方法,或者如果您的设计允许它将result的类型更改为List<..>

Your code is equivalent: 您的代码是等效的:

// Create new List by calling ToList()
var anotherList = results.ToList();
anotherList.AddRange(...);

So, you actually add items into anotherList , not result list at all. 因此,您实际上将项目添加到anotherList ,而不是result列表中。

To get the correct result, two approaches: 为了获得正确的结果,有两种方法:

1: 1:

Declare results as out and assign back: results声明为out并分配回去:

results = anotherList;

Or: 要么:

results = results.ToList().AddRange(...)

2: 2:

Use Add method supported by IList instead of AddRange 使用IList支持的Add方法代替AddRange

It's simple: 这很简单:

public static class ListExtensions
{
    public static IList<T> AddRange<T>(this IList<T> list, IEnumerable<T> range)
    {
        foreach (var r in range)
        {
            list.Add(r);
        }
        return list;
    }
}

Although IList<T> doesn't have an AddRange() , it does have Add() , so you could write an extension method for IList<T> that would let you add a range to it. 尽管IList<T>没有AddRange() ,但确实具有Add() ,所以您可以IList<T>编写扩展方法,以便向其添加范围。

If you did, your code would become: 如果这样做,您的代码将变为:

private void AddAliasesThatContainsCtid(string ctid, IList<MamConfiguration_V1> results)
{
...
    results.AddRange(mMaMDBEntities.MamConfigurationToCTIDs_V1
        .Where(item => item.CTID == aliasId)
        Select(item => item.MamConfiguration_V1));
   }
}

Compilable sample implementation: 编译示例实现:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Demo
{
    internal class Program
    {
        static void Main()
        {
            IList<string> list = new List<string>{"One", "Two", "Three"};
            Print(list);
            Console.WriteLine("---------");

            var someMultiplesOfThree = Enumerable.Range(0, 10).Where(n => (n%3 == 0)).Select(n => n.ToString());
            list.AddRange(someMultiplesOfThree); // Using the extension method.

            // Now list has had some items added to it.
            Print(list);
        }

        static void Print<T>(IEnumerable<T> seq)
        {
            foreach (var item in seq)
                Console.WriteLine(item);
        }
    }

    // You need a static class to hold the extension method(s):

    public static class IListExt
    {
        // This is your extension method:

        public static IList<T> AddRange<T>(this IList<T> @this, IEnumerable<T> range)
        {
            foreach (var item in range)
                @this.Add(item);

            return @this;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM