不能将List <T>隐式转换为Collection <T>

这是一个编译器错误(为了可读性而稍作修改)。

这一个总是困惑我。 FxCop告诉这是一个不好的事情返回列表和派生从Collection<T>应该是可取的返回types。

此外,FxCop说可以使用List<T>进行内部数据存储\操作。 好吧,我明白了,但我没有得到的是编译器抱怨尝试隐式转换List<T>Collection<T> 。 是不是更多的界面充电和function? 为什么禁止隐式转换?

而另一个源于上面的问题是: new List<int>(some collection<int>)构造函数是否昂贵?

谢谢,

瓦伦丁·瓦西里耶夫

List<T>不是从Collection<T>派生的,但是它实现了ICollection<T> 。 这将是更好的select返回types。

至于new List<int>(some collection<int>)问题,它部分取决于集合是什么。 如果它实现了ICollection<T> (在执行时),那么构造函数可以使用它的Count属性创build具有正确初始容量的列表,然后迭代并添加每个项目。 如果它没有实现ICollection<T>那么它就等于:

 List<int> list = new List<int>(); foreach (int x in otherCollection) { list.Add(x); } 

仍然很高兴有一个方便的构造,但不是非常有效 – 它不能,真的。

我不相信构造函数会对数组做任何狡猾的操作,它可能会使用Array.Copy或其他任何方法来Array.Copy复制整个区域,而不是一次次迭代。 (同样,如果它是另一个List<T>它可以得到支持数组,并直接复制)。

为什么不只是做到以下几点:

 Collection<string> collection = new Collection<string>(theList); 

作为集合(IListinput)采取列表作为一部分的build设。

List<T>不从Collection<T>inheritance。 干净利落。 除非List<T>提供一个操作符隐式地转换为Collection<T> ,否则不能这样做。 如果可以的话,我实际上会build议返回List<T> ,因为我相信规则是这样的:

接受作为参数的可能性最小的紧缩接口。 作为返回参数返回可能的最紧缩types。

这是一个用C#3.0编写的通用扩展方法,用于将List<T>转换为Collection<T>

 using System.Collections.Generic; using System.Collections.ObjectModel; public static class ExtensionMethods { public static Collection<T> ToCollection<T>(this List<T> items) { Collection<T> collection = new Collection<T>(); for (int i = 0; i < items.Count; i++) { collection.Add(items[i]); } return collection; } } 

它是这样使用…

 List<string> entities = new List<string>(); entities.Add("Value 1"); entities.Add("Value 2"); entities.Add("Value 3"); entities.Add("Value 4"); Collection<string> convertedEntities = entities.ToCollection<string>(); 

这是你如何从List<T>转换为Collection<T> (同时使用LINQ):

旧function:

 public List<Employee> GetEmployee(int id) { return ( from e in MyDataContext.Employees select new Employee() { e.empId = id } ).ToList(); } 

转换后:

 using System.Collection.ObjectModel; public Collection<Employee> GetEmployee(int id) { return new Collection<Employee>( (from e in MyDataContext.Employees select new Employee() { e.empId = id } ).ToList() as IList<Employee> ); } 

你可以使用下面的

 public class EmployeeCollection : Collection<Employee> { public EmployeeCollection(IList<Employee> list) : base(list) {} public EmployeeCollection() : base() {} } 

像这样使用这个类

 EmployeeCollection employeeCollection = new EmployeeCollection(list)