Questo non risponde necessariamente alla domanda originale, ma estende in parte alcune delle possibilità delineate. Sto postando questo nel caso in cui altri si imbattano nel problema simile. La soluzione pubblicata qui delinea un ordine generico per opzione che potrebbe essere utile in altri casi. In questo esempio, ho voluto ordinare un elenco di file con proprietà diverse.
/// <summary>
/// Used to create custom comparers on the fly
/// </summary>
/// <typeparam name="T"></typeparam>
public class GenericCompare<T> : IComparer<T>
{
// Function use to perform the compare
private Func<T, T, int> ComparerFunction { set; get; }
// Constructor
public GenericCompare(Func<T, T, int> comparerFunction)
{
ComparerFunction = comparerFunction;
}
// Execute the compare
public int Compare(T x, T y)
{
if (x == null || y == null)
{
// These 3 are bell and whistles to handle cases where one of the two is null, to sort to top or bottom respectivly
if (y == null && x == null) { return 0; }
if (y == null) { return 1; }
if (x == null) { return -1; }
}
try
{
// Do the actual compare
return ComparerFunction(x, y);
}
catch (Exception ex)
{
// But muffle any errors
System.Diagnostics.Debug.WriteLine(ex);
}
// Oh crud, we shouldn't be here, but just in case we got an exception.
return 0;
}
}
Poi nella realizzazione ...
GenericCompare<FileInfo> DefaultComparer;
if (SortOrder == SORT_FOLDER_FILE)
{
DefaultComparer = new GenericCompare<FileInfo>((fr1, fr2) =>
{
return fr1.FullName.ToLower().CompareTo(fr2.FullName.ToLower());
});
}
else if (SortOrder == SORT_SIZE_ASC)
{
DefaultComparer = new GenericCompare<FileInfo>((fr1, fr2) =>
{
return fr1.Length.CompareTo(fr2.Length);
});
}
else if (SortOrder == SORT_SIZE_DESC)
{
DefaultComparer = new GenericCompare<FileInfo>((fr1, fr2) =>
{
return fr2.Length.CompareTo(fr1.Length);
});
}
else
{
DefaultComparer = new GenericCompare<FileInfo>((fr1, fr2) =>
{
return fr1.Name.ToLower().CompareTo(fr2.Name.ToLower());
});
}
var ordered_results = (new DirectoryInfo(@"C:\Temp"))
.GetFiles()
.OrderBy(fi => fi, DefaultComparer);
Il grande vantaggio è che allora non c'è bisogno di creare una nuova classe per ogni ordine per caso, si può semplicemente collegare un nuovo lambda. Ovviamente questo può essere esteso in tutti i modi, quindi speriamo che aiuti qualcuno, da qualche parte, a volte.
fonte
2013-09-01 05:32:44
Collegamenti di qualità linq! Sebbene l'affermazione sulla sintassi order-by nella sintassi basata sul metodo non avrebbe dovuto far parte della risposta. :) –
@SteveKonves L'ho appena incluso comunque. Puoi facilmente ignorare;) –