我正在尝试使用 Reflection GetProperty
设置要动态 的OrderBy
的类型。 orderByParam
的值例如为"Length"
,"Name"
,"CreationTime"
等。这将允许我按照以后想要的顺序将文件添加到列表中。 。我收到的错误是:
对象与目标类型不匹配
。我在这里想念什么?
try
{
PropertyInfo propertyInfo = typeof(FileInfo).GetProperty(orderByParam);
var files = Directory.GetFiles(strPath)
.OrderBy(f => propertyInfo.GetValue(orderByParam, null));
//FileInfo(f).CreationTime))
foreach (string str in files)
{
strFiles.Add(Path.GetFileName(str));
}
}
答案 0 :(得分:1)
将其放置为
PropertyInfo propertyInfo = typeof(FileInfo).GetProperty(orderByParam);
var files = Directory
.EnumerateFiles(strPath)
.OrderBy(f => propertyInfo.GetValue(new FileInfo(f), null));
由于您希望从f
(确切地说是new FileInfo(f)
)而不是orderByParam
中读取属性值
答案 1 :(得分:0)
问题是您没有在OrderBy中使用参数f
.OrderBy(f => propertyInfo.GetValue(orderByParam, null));
您使事情变得比所需的复杂。
要求:给出目录的名称,以及FileInfo类的属性之一的名称,请给我该属性对该目录中所有文件的顺序。
我的建议是不要为此使用反射,而应为您的订购创建一个IComparer类。
这有几个优点。反思是相当缓慢的。比较器也可以用于OrderByDescending。但是最重要的优点是,您可以控制要订购的PropertyName。
您可以拒绝按属性Directory
或按属性Exists
订购。除了通过“ Length”增加对订单的支持之外,您还可以通过“ LENGTH” /“ length” /“ lENgth”增加对订单的支持。如果需要支持命令行输入,则可以通过“ -l” /“-L”来添加对订单的支持
如果创建比较器类,则用法为:
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);
IComparer的实现非常简单:
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));
}
}
我创建了一个私有构造函数,因此只有Create函数才能创建此比较器。
用法:
var comparer = FileInfoComparer.Create(“ Length”); DirectoryInfo目录=新的DirectoryInfo(directoryPath); varorderedFiles = directory.EnumerateFiles.Orderby(file => file,比较器);