Ceci est une erreur du compilateur (légèrement modifiée pour la lisibilité).
Celui-ci m'a toujours intrigué. FxCop indique qu'il est mauvais de renvoyer une liste et que les classes\dérivées de Collection<T>
devraient être préférables en tant que types de retour.
En outre, FxCop indique qu'il est correct d'utiliser List<T>
pour le stockage de données interne\manipulation ..__ OK, je comprends, mais ce que je ne comprends pas, c'est que le compilateur se plaint d'avoir tenté de convertir implicitement List<T>
en Collection<T>
. List<T>
n'est-il pas plus chargé d'interface et fonctionnel? Pourquoi interdire la conversion implicite?
Et une autre question qui vient d’en haut: le constructeur new List<int>(some collection<int>)
est-il cher?
Je vous remercie,
Valentin Vasiliev
List<T>
ne dérive pas de Collection<T>
- il implémente toutefois ICollection<T>
. Ce serait un meilleur choix de type de retour.
Quant à la question new List<int>(some collection<int>)
- cela dépend en partie de ce que la collection est. S'il implémente ICollection<T>
(au moment de l'exécution), le constructeur peut utiliser sa propriété Count
pour créer la liste avec la bonne capacité initiale avant de l'itérer et d'ajouter chaque élément. S'il n'implémente pas ICollection<T>
, c'est simplement équivalent à:
List<int> list = new List<int>();
foreach (int x in otherCollection)
{
list.Add(x);
}
Toujours agréable d'avoir un constructeur pratique, mais pas extrêmement efficace - ça ne peut pas être, vraiment.
Je ne crois pas que le constructeur fasse quelque chose de rusé pour les tableaux, ce qu'il pourrait potentiellement - en utilisant Array.Copy
ou autre pour copier simplement le lot en une seule fois plutôt que d'itérer. (De même, s'il s'agissait d'un autre List<T>
, il pourrait accéder directement au tableau de sauvegarde et le copier.)
Pourquoi ne pas simplement faire ce qui suit:
Collection<string> collection = new Collection<string>(theList);
as Collection (entrée IList) prend une liste dans le cadre de la construction.
List<T>
n'hérite pas de Collection<T>
. Clair et simple. À moins que List<T>
ne fournisse un opérateur pour convertir implicitement vers/depuis Collection<T>
, vous ne pouvez pas le faire. En fait, je suggèrerais de renvoyer List<T>
si vous le pouvez, car je crois que les règles vont comme ceci:
Accepter comme paramètre l'interface la moins contraignante possible. Retourne comme paramètre de retour le type le plus contraignant possible.
Voici une méthode d'extension générique écrite en C # 3.0 utilisée pour convertir List<T>
en 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;
}
}
et c'est utilisé comme ça…
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>();
Vous pouvez utiliser le la ci-dessous
public class EmployeeCollection : Collection<Employee>
{
public EmployeeCollection(IList<Employee> list) : base(list)
{}
public EmployeeCollection() : base()
{}
}
Utilisez la classe comme ça
EmployeeCollection employeeCollection = new EmployeeCollection(list)
Voici comment vous convertissez de List<T>
à Collection<T>
(avec LINQ):
L'ancienne fonction:
public List<Employee> GetEmployee(int id)
{
return ( from e in MyDataContext.Employees
select new Employee()
{
e.empId = id
}
).ToList();
}
Après conversion:
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>
);
}