Então me deparei com um problema interessante hoje. Temos um serviço da web WCF que retorna um IList. Não era realmente grande coisa até que eu quisesse resolver isso.
Acontece que a interface IList não tem um método de classificação embutido.
Acabei usando o ArrayList.Adapter(list).Sort(new MyComparer())
método para resolver o problema, mas parecia um pouco "gueto" para mim.
Eu brinquei em escrever um método de extensão, também em herdar de IList e implementar meu próprio método Sort (), bem como lançar para um List, mas nenhum deles parecia excessivamente elegante.
Então, minha pergunta é, alguém tem uma solução elegante para classificar um ILista
Respostas:
Que tal usar LINQ To Objects para classificar para você?
Digamos que você tenha um
IList<Car>
, e o carro tenha umaEngine
propriedade, acredito que você possa classificar da seguinte forma:Edit: Você precisa ser rápido para obter respostas aqui. Como apresentei uma sintaxe um pouco diferente para as outras respostas, deixarei minha resposta - entretanto, as outras respostas apresentadas são igualmente válidas.
fonte
Você pode usar o LINQ:
fonte
Esta pergunta me inspirou a escrever uma postagem no blog: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
Acho que, idealmente, o .NET Framework incluiria um método de classificação estático que aceita um IList <T>, mas a próxima melhor coisa é criar seu próprio método de extensão. Não é muito difícil criar alguns métodos que permitirão que você classifique um IList <T> como faria com um List <T>. Como bônus, você pode sobrecarregar o método de extensão LINQ OrderBy usando a mesma técnica, de forma que, se estiver usando List.Sort, IList.Sort ou IEnumerable.OrderBy, você poderá usar exatamente a mesma sintaxe.
Com essas extensões, classifique seu IList como se fosse uma lista:
Há mais informações na postagem: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
fonte
ISortableList<T>
interface (com métodos para classificar uma parte da lista usando algum comparador específico),List<T>
implementá-la e ter um método estático que pudesse classificar qualquer umaIList<T>
, verificando se ela foi implementadaISortableList<T>
e, se não, copiando-o para uma matriz, classificando-a, limpandoIList<T>
e readicionando os itens.IList<T> list
pode ser convertido para aIList
interface não genérica . Se você codificar sua própria classe implementando aIList<T>
interface, certifique-se de implementar também o método não genéricoIList
interface , ou o código falhará com uma exceção de conversão de classe.ISortableList<T>
oferecer que ainda não foi lançadoIList<T>
? Ou, de outra forma, por que não poderiaIList<T>
ser classificado no local sem readicionar os itens pelo seu método estático imaginado?IList<T>
interface para acessar cada elemento. A diferença de velocidade é grande o suficiente para que, em muitos casos, seja mais rápido copiar uma lista para um array, classificar o array e copiar a lista de volta do que tentar fazer com que uma rotina de classificação processe a lista no local.ComparisonComparer
aula não é necessária. Você pode usar o método estático padrãoComparer<T>.Create(comparison)
.Você vai ter que fazer algo assim, eu acho (convertê-lo em um tipo mais concreto).
Talvez inclua em uma List of T em vez de ArrayList, para obter segurança de tipo e mais opções de como implementar o comparador.
fonte
A resposta aceita por @DavidMills é muito boa, mas acho que pode ser melhorada. Por um lado, não há necessidade de definir a
ComparisonComparer<T>
classe quando o framework já inclui um método estáticoComparer<T>.Create(Comparison<T>)
. Este método pode ser usado para criar umIComparison
em tempo real.Além disso, ele transmite
IList<T>
para oIList
qual tem potencial para ser perigoso. Na maioria dos casos que vi, oList<T>
que implementaIList
é usado nos bastidores para implementarIList<T>
, mas isso não é garantido e pode levar a um código frágil.Por último, o
List<T>.Sort()
método sobrecarregado possui 4 assinaturas e apenas 2 delas estão implementadas.List<T>.Sort()
List<T>.Sort(Comparison<T>)
List<T>.Sort(IComparer<T>)
List<T>.Sort(Int32, Int32, IComparer<T>)
A classe abaixo implementa todas as 4
List<T>.Sort()
assinaturas para aIList<T>
interface:Uso:
A ideia aqui é aproveitar a funcionalidade do subjacente
List<T>
para lidar com a classificação sempre que possível. Novamente, a maioria dasIList<T>
implementações que vi usa isso. No caso em que a coleção subjacente é de um tipo diferente, volte para a criação de uma nova instância deList<T>
com elementos da lista de entrada, use-a para fazer a classificação e copie os resultados de volta para a lista de entrada. Isso funcionará mesmo se a lista de entrada não implementar aIList
interface.fonte
fonte
Encontrei este tópico enquanto procurava uma solução para o problema exato descrito no post original. Nenhuma das respostas atendeu inteiramente a minha situação, no entanto. A resposta de Brody foi bem próxima. Aqui está minha situação e a solução que encontrei para ela.
Eu tenho dois IList do mesmo tipo retornados por NHibernate e emergi os dois IList em um, daí a necessidade de classificação.
Como o Brody disse, implementei um ICompare no objeto (ReportFormat) que é o tipo do meu IList:
Em seguida, converto o IList mesclado em uma matriz do mesmo tipo:
Em seguida, classifique a matriz:
Visto que o array unidimensional implementa a interface
System.Collections.Generic.IList<T>
, o array pode ser usado como o IList original.fonte
Útil para classificação em grade, este método classifica a lista com base nos nomes das propriedades. Siga o exemplo.
fonte
Aqui está um exemplo usando a digitação mais forte. Não tenho certeza se é necessariamente a melhor maneira.
A função Cast é apenas uma reimplementação do método de extensão que vem com o 3.5 escrito como um método estático normal. É muito feio e prolixo, infelizmente.
fonte
No VS2008, quando clico na referência do serviço e seleciono "Configurar Referência do Serviço", há uma opção de escolher como o cliente desserializa as listas retornadas do serviço.
Notavelmente, posso escolher entre System.Array, System.Collections.ArrayList e System.Collections.Generic.List
fonte
Isso é lindo! Gueto.
fonte
Encontrei um bom post sobre isso e pensei em compartilhar. Confira aqui
Basicamente.
Você pode criar a seguinte classe e classes IComparer
Então, se você tiver um IList, você pode classificá-lo assim.
Mas verifique este site para mais informações ... Confira AQUI
fonte
Esta é uma solução válida?
O resultado foi: IList B A C
Lista A B C
ILista novamente A B C
fonte
Isso parece MUITO MAIS SIMPLES se você me perguntar. Isso funciona perfeitamente para mim.
Você pode usar Cast () para alterá-lo para IList e usar OrderBy ():
ONDE T é o tipo, por exemplo. Model.Employee ou Plugin.ContactService.Shared.Contact
Então você pode usar um loop for e seu DONE.
fonte
Converta o seu
IList
emList<T>
ou alguma outra coleção genérica e então você pode facilmente consultar / classificar usando oSystem.Linq
namespace (ele fornecerá vários métodos de extensão)fonte
IList<T>
implementaIEnumerable<T>
e, portanto, não precisa ser convertido para usar as operações do Linq.