C# 将列表项添加到集合时,AddRange()不起作用
最近我接到一个任务,要处理一个FxCop警告-不要公开通用列表。因此,我尝试将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
列表更改为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
,但没有)