web-dev-qa-db-ja.com

List <T>をCollection <T>に暗黙的に変換できません

これはコンパイラエラーです(読みやすくするために少し変更されています)。

これはいつも私を困惑させました。 FxCopは、これはListを返すのは悪いことであり、_Collection<T>_から派生したクラスは戻り型として優先されるべきであると伝えています。

また、FxCopは、内部データストレージ\操作に_List<T>_を使用しても問題ないと述べています。わかりましたが、得られないのは、コンパイラが_List<T>_を_Collection<T>_に暗黙的に変換しようとすると文句を言うことです。 _List<T>_は、より多くのインターフェイスで機能し、機能していませんか?暗黙の変換を禁止する理由

そして、上記に由来する別の質問:new List<int>(some collection<int>)コンストラクターは高価ですか?

ありがとうございました、

バレンティン・ヴァシリエフ

41
Valentin

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

便利なコンストラクターを使用することはできますが、それほど効率的ではありません。実際には不可能です。

私はコンストラクタが配列に対してcなことをすることはないと思います-それは可能性があります-_Array.Copy_または何かを使用して、繰り返しではなく一度にたくさんをコピーします。 (同様に、それが別の_List<T>_である場合、バッキング配列に到達し、それを直接コピーできます。)

36
Jon Skeet

なぜ次のことをしないのですか:

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

as Collection(IList input)はリストを構築の一部として受け取ります。

91
Matthew M.

List<T>Collection<T>から継承しません。簡潔でシンプル。 List<T>Collection<T>との間で暗黙的に変換する演算子を提供しない限り、それを行うことはできません。できればList<T>を返すことをお勧めします。ルールは次のようになっていると思います。

可能な限り最も制約の少ないインターフェースをパラメーターとして受け入れます。可能な限り最も厳密な型を戻りパラメータとして返します。

6
David Morton

以下は、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
Keith Beller

以下を使用できます

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

      public EmployeeCollection() : base()
      {}

}

このようなクラスを使用してください

EmployeeCollection  employeeCollection = new EmployeeCollection(list)
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>
           );
}
0
Shadi Namrouti