猿问

C# 使用 GetProperty 进行 LINQ OrderBy 使用 FileInfo

我正在尝试使用反射来 动态设置我想要GetProperty的类型。将有一个值,例如, ,等。这将允许我以后按我想要的顺序将文件添加到列表中。我收到的错误是:OrderByorderByParam"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));

    }

}


白衣染霜花
浏览 188回答 2
2回答

慕桂英546537

把它当作 PropertyInfo propertyInfo = typeof(FileInfo).GetProperty(orderByParam); var files = Directory   .EnumerateFiles(strPath)   .OrderBy(f => propertyInfo.GetValue(new FileInfo(f), null));  f由于您希望从(new FileInfo(f)准确地说)读取属性值,所以不orderByParam

隔江千里

问题是您没有在 OrderBy 中使用参数 f.OrderBy(f => propertyInfo.GetValue(orderByParam, null));&nbsp;你让事情变得比需要的更复杂。要求:给定一个目录的名称,以及类 FileInfo 的属性之一的名称,给我这个目录中由这个属性排序的所有文件的顺序。我的建议是不要为此使用反射,而是为您的订购创建一个 IComparer 类。这有几个优点。反射相当缓慢。比较器也可以用于 OrderByDescending。但最重要的优势是您可以控制要订购的 PropertyNames。您可以拒绝按属性订购,也可以按属性拒绝Directory订购Exists。除了通过“长度”添加对订单的支持之外,您还可以通过“长度”/“长度”/“长度”添加对订单的支持。如果需要支持命令行输入,可以通过“-l”/“-L”添加对命令的支持如果您创建一个比较器类,用法将是:string directoryName = ...// TODO: exception if directoryName null or emptyDirectoryInfo directory = new DirectoryInfo(directoryName);if (!directory.Exists) TODO: exceptionIComparer<FileInfo> comparer = ...IEnumerable<FileInfo> files = directory.EnumerateFiles();IEnumerable<FileInfo> orderedFiles = files.OrderBy(file => file, comparer);IComparer 的实现相当简单:class FileInfoComparer<TKey> : IComparer<FileInfo>{&nbsp; &nbsp; public static IComparer<FileInfo> Create(string propertyName)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // this Compare supports only property names of FileInfo&nbsp; &nbsp; &nbsp; &nbsp; // and maybe not even all property names&nbsp; &nbsp; &nbsp; &nbsp; switch (propertyName)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "Name":&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new FileInfoComparer(fileInfo => fileInfo.Name);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "Length":&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new FileInfoComparer(fileInfo => fileInfo.Length);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "Extension"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new FileInfoComparer(fileInfo => fileInfo.Extension);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;throw new NotSupportedException("Ordering by this property not supported");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// for instance: property names "Directory" "Exists"&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private FileInfoComparer(Func<FileInfo, TKey> keySelector)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; this.keySelector = keySelector;&nbsp; &nbsp; }&nbsp; &nbsp; private readonly Func<FileInfo, TKey> keySelector;&nbsp; &nbsp; private readonly IComparer<TKey> keyComparer = Comparer<TKey>.Default;&nbsp; &nbsp; public int Compare(FileInfo x, FileInfo y)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // TODO: decide what to do if x or y null. Exception? first or last in sort order?&nbsp; &nbsp; &nbsp; &nbsp; return keyComparer.Compare(this.keySelector(x), this.keySelector(y));&nbsp; &nbsp; }}我创建了一个私有构造函数,所以只有 Create 函数可以创建这个比较器。用法:var comparer = FileInfoComparer.Create("Length"); DirectoryInfo 目录 = 新 DirectoryInfo(directoryPath); var orderedFiles = directory.EnumerateFiles.Orderby(file => file, comparer);
随时随地看视频慕课网APP
我要回答