Respostas:
Da mesma forma que você classificaria qualquer outro enumerável:
var result = myEnumerable.OrderBy(s => s);
ou
var result = from s in myEnumerable
orderby s
select s;
ou (ignorando maiúsculas e minúsculas)
var result = myEnumerable.OrderBy(s => s,
StringComparer.CurrentCultureIgnoreCase);
Observe que, como é normal com LINQ, isso cria um novo IEnumerable <T> que, quando enumerado, retorna os elementos do IEnumerable <T> original na ordem de classificação. Ele não classifica o IEnumerable <T> no local.
Um IEnumerable <T> é somente leitura, ou seja, você só pode recuperar os elementos dele, mas não pode modificá-lo diretamente. Se você deseja classificar uma coleção de strings no local, você precisa classificar a coleção original que implementa IEnumerable <string> ou transformar um IEnumerable <string> em uma coleção classificável primeiro:
List<string> myList = myEnumerable.ToList();
myList.Sort();
Com base em seu comentário:
_components = (from c in xml.Descendants("component")
let value = (string)c
orderby value
select value
)
.Distinct()
.ToList();
ou
_components = xml.Descendants("component")
.Select(c => (string)c)
.Distinct()
.OrderBy(v => v)
.ToList();
ou (se quiser adicionar mais itens à lista posteriormente e mantê-la classificada)
_components = xml.Descendants("component")
.Select(c => (string)c)
.Distinct()
.ToList();
_components.Add("foo");
_components.Sort();
OrderBy
retorna IOrderedEnumerable<T>
. IOrderedEnumerable<T>
deriva de IEnumerable<T>
para que possa ser usado como IEnumerable<T>
, mas estende o tipo, permitindo por exemplo, o uso de ThenBy
.
É impossível, mas não é.
Basicamente, qualquer método de classificação irá copiar seu IEnumerable
em um List
, classificar o List
e, em seguida, retornar para você a lista classificada, que é tanto um IEnumerable
quanto um IList
.
Isso significa que você perde a propriedade "continuar infinitamente" de um IEnumerable
, mas não pode classificar um assim de qualquer maneira.
Nem sempre podemos fazer isso no local, mas detectamos quando é possível:
IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src, IComparer<T> cmp)
{
List<T> listToSort = (src is List<T>) ? (List<T>)src : new List<T>(src);
listToSort.Sort(cmp);
return listToSort;
}
IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src, Comparison<T> cmp)
{
return SortInPlaceIfCan(src, new FuncComparer<T>(cmp));
}
IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src)
{
return SortInPlaceIfCan(src, Comparer<T>.Default);
}
Isso usa a seguinte estrutura útil:
internal struct FuncComparer<T> : IComparer<T>
{
private readonly Comparison<T> _cmp;
public FuncComparer(Comparison<T> cmp)
{
_cmp = cmp;
}
public int Compare(T x, T y)
{
return _cmp(x, y);
}
}
listToSort = (src is List<T>) ? (List<T>)src : new List<T>(src);
? Que tal ter comolistToSort = (src as List<T>); if (null == listToSort) listToSort = new List<T>(src);