C# 将列表项添加到集合时,AddRange()不起作用

C# 将列表项添加到集合时,AddRange()不起作用,c#,generics,generic-collections,C#,Generics,Generic Collections,最近我接到一个任务,要处理一个FxCop警告-不要公开通用列表。因此,我尝试将列表更改为ICollection。但是后来,在进行单元测试时,我发现AddRange()没有按照预期正常工作。它不是将元素集合添加到集合对象 下面是示例代码 gc.ToList().AddRange(sampleList); 我有两个问题要问 为什么不将项目添加到集合中。 代码如下: public class GenericClass { public int Id; public string Na

最近我接到一个任务,要处理一个FxCop警告-不要公开通用列表。因此,我尝试将
列表更改为
ICollection
。但是后来,在进行单元测试时,我发现
AddRange()
没有按照预期正常工作。它不是将元素集合添加到集合对象

下面是示例代码

gc.ToList().AddRange(sampleList);
我有两个问题要问

  • 为什么不将项目添加到集合中。 代码如下:

    public class GenericClass
    {
        public int Id;
        public string Name;
    }  
    
    
    class Program
    {
         static void Main(string[] args)
         {
    
          ICollection<GenericClass> gc = new  List<GenericClass>();
    
        var sampleList = new List<GenericClass>()
                             {
                                 new GenericClass {Id = 1, Name = "ASD"},
                                 new GenericClass {Id = 2, Name = "QWER"},
                                 new GenericClass {Id = 3, Name = "BNMV"},
                             };
    
        Console.WriteLine(gc.GetType()); // gc is of type
    
        gc.ToList().AddRange(sampleList); // sampleList items are not getting added to gc.
        Console.ReadKey();
    }
    
    公共类GenericClass
    {
    公共int Id;
    公共字符串名称;
    }  
    班级计划
    {
    静态void Main(字符串[]参数)
    {
    ICollection gc=新列表();
    var sampleList=新列表()
    {
    新的泛型类{Id=1,Name=“ASD”},
    新的泛型类{Id=2,Name=“QWER”},
    新的泛型类{Id=3,Name=“BNMV”},
    };
    Console.WriteLine(gc.GetType());//gc的类型为
    gc.ToList().AddRange(sampleList);//没有将sampleList项添加到gc中。
    Console.ReadKey();
    }
    
    }

  • List
    继承自
    ICollection
    List
    具有
    AddRange()
    等功能。当我试图将父引用(
    ICollection
    )强制转换为子类对象(
    List
    )时,为什么Intellisense不建议
    AddRange()
    。相反,我需要执行
    .ToList()
    ,然后它显示
    AddRange()

  • 我找了很多这个。但是找不到让我满意的理由。所以请帮助我理解。这将是一个很大的帮助。

    方法运行良好。问题是,您没有仔细阅读
    ToList()
    扩展方法的文档,因此没有意识到
    ToList()
    方法返回一个全新的对象

    发件人:

    从IEnumerable创建列表

    由于调用的对象
    AddRange()
    实际上不是原始集合,因此原始集合保持不变

    从某种意义上说,您的问题是
    列表
    相当于非常常见的问题“为什么
    string.Replace()
    不起作用?”

    在您给出的示例中,没有比不首先隐藏
    列表
    更好的解决方案了。由于您使用的是通用的
    ICollection
    接口,因此可以编写自己的
    AddRange()
    作为扩展方法:

    public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> range)
    {
        foreach (T t in range)
        {
            collection.Add(t);
        }
    }
    
    publicstaticvoidaddrange(此ICollection集合,IEnumerable范围)
    {
    foreach(T在范围内)
    {
    集合。添加(t);
    }
    }
    
    但是,如果目标是能够修改对象并使用
    AddRange()
    方法,我不认为这真的比将类型保留为
    List
    要好得多

    ICollection
    引用转换回其底层
    列表(正如另一位回答者所建议的)是毫无意义的,因为这样做首先会否定使用
    ICollection
    接口的任何价值

    只需将引用保留为
    列表
    ,至少在实际需要修改集合的任何上下文中。(只使用
    ICollection
    在其他上下文中公开该列表是很好的,甚至可能是有益的,但这是一个完全不同的讨论。)

    只要我回答,我就要提到,我怀疑您是否正确理解了FxCop警告的意图,因为公开泛型列表本身并不有害。

    ToList()
    返回一个新实例,这就是为什么您无法在“gc”中看到AddRange的结果。如果您确实想使用AddRange,可以执行以下操作

    ((List<GenericClass>)gc).AddRange(sampleList);
    
    ((List)gc).AddRange(sampleList);
    
    在我将.ToList()放入对象之后,请您更详细地说明语句,这样只有我才能看到AddRange函数。您的答案是关于问题(1)或(2)ICollection接口根本不允许修改集合。请你详细说明一下那项声明好吗。您能提供一个如何向集合对象添加项目的解决方案吗???
    ICollection接口根本不允许修改集合。
    这是错误的。ICollection接口根本不允许修改集合。但是当我尝试执行ToList().AddRange(simpleList)时。为什么不将列表附加到集合对象。gc.ToList().AddRange(sampleList)@mjwills:谢谢……你不会相信的,但我确实看过文档,确定有Add()方法,但找不到,所以写了我所做的。看起来我对
    ICollection
    ICollection
    感到困惑(OP的原始帖子有一些格式问题,通用语法没有出现)。@Vijay:当我在声明中写
    ICollection
    时,我实际上想到的是
    ICollection
    。您可以修改
    ICollection
    …查看上面我编辑的答案。关于这一点:“为什么列表没有被附加到集合对象”,我在第一段中直接回答:当您调用
    AddRange()
    时,该方法应用到的
    这个
    对象不是您开始使用的
    gc
    对象。它是由
    ToList()
    方法返回的全新
    List
    对象。将
    ICollection
    更改为
    var
    。没有理由在该上下文中使用
    ICollection
    但找不到令我满意的理由。
    您告诉
    gc
    这是一个
    ICollection
    ICollection
    缺少
    AddRange
    (它确实有
    Add
    ,但没有