whereselectlistiterator wherelistiterator tipo puede objeto lista implícitamente generic convertir c# generics collections

c# - lista - no se puede convertir un objeto de tipo wherelistiterator



No se puede convertir implícitamente List<T> a Collection<T> (6)

Este es un error del compilador (ligeramente modificado para la legibilidad).

Este siempre me desconcertó. FxCop dice que devolver la Lista es malo y las clases que se derivan de la Collection<T> deberían ser preferibles como tipos de devolución.

Además, FxCop dice que está bien utilizar List<T> para el almacenamiento interno de datos / manipulación. Ok, lo entiendo, pero lo que no entiendo es que el compilador se queja de tratar de convertir implícitamente List<T> a Collection<T> . ¿No es la List<T> más cargada de interfaz y funcional? ¿Por qué prohibir la conversión implícita?

Y otra pregunta que surge de arriba: ¿es costoso el nuevo constructor new List<int>(some collection<int>) ?

Gracias,

Valentin Vasiliev


¿Por qué no solo hacer lo siguiente?

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

como Colección (entrada IList) toma una lista como parte de la construcción.


Aquí hay un método de extensión genérico escrito en C # 3.0 usado para convertir List<T> a 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; } }

y se usa así ...

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


Así es como se convierte de List<T> a Collection<T> (mientras se usa LINQ):

La vieja función:

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

Después de la conversión:

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


Puedes usar el de abajo

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

Usa la clase como esta

EmployeeCollection employeeCollection = new EmployeeCollection(list)


List<T> no hereda de Collection<T> . Simple y simple. A menos que List<T> proporcione un operador para convertir implícitamente a / de Collection<T> , no puede hacerlo. En realidad, le sugiero que devuelva List<T> si puede, ya que creo que las reglas son más o menos así:

Acepte como parámetro la interfaz menos restrictiva posible. Devuelve como parámetro de retorno el tipo más constrictivo posible.


List<T> no se deriva de Collection<T> ; sin embargo, implementa ICollection<T> . Esa sería una mejor opción de tipo de devolución.

En cuanto a la new List<int>(some collection<int>) pregunta new List<int>(some collection<int>) , depende en parte de qué es la colección. Si implementa ICollection<T> (en tiempo de ejecución), el constructor puede usar su propiedad Count para crear la lista con la capacidad inicial correcta antes de iterar a través de ella y agregar cada elemento. Si no implementa ICollection<T> , es equivalente a:

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

Es bueno tenerlo en un constructor conveniente, pero no es muy eficiente, no puede serlo realmente.

No creo que el constructor haga nada astuto para las matrices, lo que potencialmente podría hacer: usar Array.Copy o lo que sea para copiar el lote de una sola vez en lugar de iterar. (Del mismo modo, si fuera otra List<T> , podría llegar a la matriz de respaldo y copiarla directamente).