The problem is that you don't use parameter f in your OrderBy
.OrderBy(f => propertyInfo.GetValue(orderByParam, null));
You are making things way more complicated than needed.
Requirement: given the name of a Directory, and the name of one of the properties of class FileInfo, give me the sequence of all files in this directory ordered by this property.
My advise would be not to use reflection for this, but to create an IComparer class for your ordering.
This has several advantages. Reflection is fairly slow. The comparer can also be used to OrderByDescending. But the most important advantage is that you can control which PropertyNames you want to order by.
You can refuse ordering by property Directory
, or by property Exists
. Besides to add support to order by "Length" you can add support to order by "LENGTH" / "length" / "lENgth". If you need to support command line input, you could add support to order by "-l" / "-L"
If you create a comparer class, usage would be:
string directoryName = ...
// TODO: exception if directoryName null or empty
DirectoryInfo directory = new DirectoryInfo(directoryName);
if (!directory.Exists) TODO: exception
IComparer<FileInfo> comparer = ...
IEnumerable<FileInfo> files = directory.EnumerateFiles();
IEnumerable<FileInfo> orderedFiles = files.OrderBy(file => file, comparer);
The implementation of IComparer is fairly easy:
class FileInfoComparer<TKey> : IComparer<FileInfo>
{
public static IComparer<FileInfo> Create(string propertyName)
{
// this Compare supports only property names of FileInfo
// and maybe not even all property names
switch (propertyName)
{
case "Name":
return new FileInfoComparer(fileInfo => fileInfo.Name);
case "Length":
return new FileInfoComparer(fileInfo => fileInfo.Length);
case "Extension"
return new FileInfoComparer(fileInfo => fileInfo.Extension);
...
default:
throw new NotSupportedException("Ordering by this property not supported");
// for instance: property names "Directory" "Exists"
}
}
private FileInfoComparer(Func<FileInfo, TKey> keySelector)
{
this.keySelector = keySelector;
}
private readonly Func<FileInfo, TKey> keySelector;
private readonly IComparer<TKey> keyComparer = Comparer<TKey>.Default;
public int Compare(FileInfo x, FileInfo y)
{
// TODO: decide what to do if x or y null. Exception? first or last in sort order?
return keyComparer.Compare(this.keySelector(x), this.keySelector(y));
}
}
I created a private constructor, so only the Create function can create this comparer.
Usage:
var comparer = FileInfoComparer.Create("Length");
DirectoryInfo directory = new DirectoryInfo(directoryPath);
var orderedFiles = directory.EnumerateFiles.Orderby(file => file, comparer);