无法将List <t>隐式转换为Collection <t> </t> </t>

时间:2009-02-07 19:39:21

标签: c# generics collections

这是一个编译器错误(为了便于阅读,略有改动)。

这一直困扰着我。 FxCop告诉我返回List是一件坏事,而从Collection<T>派生的\类应该更适合作为返回类型。

此外,FxCop表示可以使用List<T>进行内部数据存储\操作。 好的,我明白了,但我没有得到的是编译器抱怨试图隐式地将List<T>转换为Collection<T>List<T>更多接口是否充电且功能正常? 为什么禁止隐式转换?

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

谢谢,

Valentin Vasiliev

7 个答案:

答案 0 :(得分:90)

为什么不执行以下操作:

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

as Collection(IList输入)将List作为构造的一部分。

答案 1 :(得分:35)

List<T>并非来自Collection<T> - 但它会实现ICollection<T>。那将是返回类型的更好选择。

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

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

仍然很高兴拥有一个方便的构造函数,但效率不高 - 它不可能,真的。

我不相信构造函数会对数组做任何狡猾的事情,它可能会使用Array.Copy或其他只是一次性复制批次而不是迭代。 (同样,如果它是另一个List<T>,它可以进入后备阵列并直接复制它。)

答案 2 :(得分:6)

List<T>不会从Collection<T>继承。干净利落。除非List<T>允许操作员隐式转换为Collection<T>,否则您无法执行此操作。如果可以的话,我实际建议你回复List<T>,因为我相信规则是这样的:

接受可能的最不紧缩的接口作为参数。 作为返回参数返回可能的最紧缩类型。

答案 3 :(得分:4)

以下是用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>();

答案 4 :(得分:0)

这是您从List<T>转换为Collection<T>的方式(使用LINQ时):

旧功能:

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>
           );
}

答案 5 :(得分:0)

您可以使用以下

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

      public EmployeeCollection() : base()
      {}

}

使用像这样的课程

EmployeeCollection  employeeCollection = new EmployeeCollection(list)

答案 6 :(得分:-1)

反之,则无需循环...您可以只.ToList()

    ICollection<T> collection = new Collection<T>();

使用任何方法填充您的收藏集,然后在需要列表时,只需执行以下操作:

    List<T> list = collection.ToList();

之后,您可以在列表中使用任何内容。

编码良好!