Eu defini o seguinte:
public ICollection<Item> Items { get; set; }
Quando executo este código:
Items = _item.Get("001");
Recebo a seguinte mensagem:
Error 3
Cannot implicitly convert type
'System.Collections.Generic.IEnumerable<Storage.Models.Item>' to
'System.Collections.Generic.ICollection<Storage.Models.Item>'.
An explicit conversion exists (are you missing a cast?)
Alguém pode explicar o que estou fazendo de errado. Estou muito confuso sobre a diferença entre Enumerable, Collections e o uso de ToList ()
Informação adicionada
Posteriormente em meu código, tenho o seguinte:
for (var index = 0; index < Items.Count(); index++)
Eu estaria bem em definir itens como um IEnumerable?
public IEnumerable<Item> Items { get; set; }
Você tem algum motivo especial para tê-lo comoICollection
?Respostas:
ICollection<T>
herda deIEnumerable<T>
então para atribuir o resultado deIEnumerable<T> Get(string pk)
para um,
ICollection<T>
existem duas maneiras.// 1. You know that the referenced object implements `ICollection<T>`, // so you can use a cast ICollection<T> c = (ICollection<T>)Get("pk"); // 2. The returned object can be any `IEnumerable<T>`, so you need to // enumerate it and put it into something implementing `ICollection<T>`. // The easiest is to use `ToList()`: ICollection<T> c = Get("pk").ToList();
A segunda opção é mais flexível, mas tem um impacto muito maior no desempenho. Outra opção é armazenar o resultado como um, a
IEnumerable<T>
menos que você precise da funcionalidade extra adicionada pelaICollection<T>
interface.Comentário Adicional de Desempenho
O loop que você tem
for (var index = 0; index < Items.Count(); index++)
funciona em um,
IEnumerable<T>
mas é ineficiente; cada chamada paraCount()
requer uma enumeração completa de todos os elementos. Use uma coleção e aCount
propriedade (sem parênteses) ou converta-a em um loop foreach:foreach(var item in Items)
fonte
ICollection<T>
pode ser manipulado (consulte o documento para obter detalhes), enquanto umIEnumerable<T>
só pode ser enumerado.IEnumerable<T>
entãoIEnumerable<T>
é o suficiente nesse caso.Você não pode converter diretamente de
IEnumerable<T>
paraICollection<T>
. Você pode usar oToList
método deIEnumerable<T>
para convertê-lo emICollection<T>
someICollection = SomeIEnumerable.ToList();
fonte
Mais informações pendentes sobre a questão:
forneça mais informações sobre o tipo de item e a assinatura de Get
Duas coisas que você pode tentar são:
Observe que o segundo causará um impacto no desempenho da cópia do array. Se a assinatura (tipo de retorno) de Get não for uma ICollection, a primeira não funcionará; se não for IEnumerable, a segunda não funcionará.
Seguindo seu esclarecimento à dúvida e nos comentários, eu pessoalmente declararia o tipo de retorno de _item.Get ("001") para ICollection. Isso significa que você não terá que fazer nenhuma conversão ou conversão (via ToList / ToArray) que envolveria uma operação desnecessária de criação / cópia.
// Leave this the same public ICollection<Item> Items { get; set; } // Change function signature here: // As you mention Item uses the same underlying type, just return an ICollection<T> public ICollection<Item> Get(string value); // Ideally here you want to call .Count on the collectoin, not .Count() on // IEnumerable, as this will result in a new Enumerator being created // per loop iteration for (var index = 0; index < Items.Count(); index++)
Cumprimentos,
fonte