Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#使用FileInfo为LINQ OrderBy使用GetProperty_C#_Linq_System.reflection_System.io.fileinfo - Fatal编程技术网

C#使用FileInfo为LINQ OrderBy使用GetProperty

C#使用FileInfo为LINQ OrderBy使用GetProperty,c#,linq,system.reflection,system.io.fileinfo,C#,Linq,System.reflection,System.io.fileinfo,我正在尝试使用反射GetProperty动态设置所需的OrderBy的类型。orderByParam将具有一个值,例如长度“,名称“,“CreationTime”,等等。这将允许我以后按所需顺序将文件添加到列表中。我收到的错误是: 对象与目标类型不匹配 。我错过了什么 try { PropertyInfo propertyInfo = typeof(FileInfo).GetProperty(orderByParam); var files = Directory.GetFile

我正在尝试使用反射
GetProperty
动态设置所需的
OrderBy
的类型。
orderByParam
将具有一个值,例如
长度“
名称“
“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));
    }
}
把它当作

 PropertyInfo propertyInfo = typeof(FileInfo).GetProperty(orderByParam);

 var files = Directory
   .EnumerateFiles(strPath)
   .OrderBy(f => propertyInfo.GetValue(new FileInfo(f), null));  

由于您希望从
f
newfileinfo(f)
)读取属性值,而不是从
orderByParam

读取属性值,因此问题在于您没有在OrderBy中使用参数f

.OrderBy(f => propertyInfo.GetValue(orderByParam, null)); 
你让事情变得比需要的更复杂

要求:给定一个目录的名称和类FileInfo的一个属性的名称,给我这个目录中所有文件的顺序,按这个属性排序

我的建议是不要为此使用反射,而是为您的订购创建一个IComparer类

这有几个优点。反射相当慢。比较器还可以用于按降序排序。但最重要的优点是,您可以控制要按哪个属性名称订购

您可以按属性
目录
,或按属性
存在
拒绝订购。除了按“长度”添加对订单的支持外,您还可以按“长度”/“长度”/“长度”添加对订单的支持。如果您需要支持命令行输入,您可以通过“-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);
string directoryName=。。。
//TODO:如果directoryName为null或为空,则出现异常
DirectoryInfo directory=新的DirectoryInfo(directoryName);
如果(!directory.Exists)TODO:异常
IComparer比较器=。。。
IEnumerable files=目录.EnumerateFiles();
IEnumerable 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));
    }

}
类文件信息比较器:IComparer
{
公共静态IComparer创建(字符串属性名称)
{
//此比较仅支持FileInfo的属性名称
//甚至可能不是所有的财产名称
交换机(propertyName)
{
案例“名称”:
返回新的FileInfoComparer(fileInfo=>fileInfo.Name);
案例“长度”:
返回新的FileInfoComparer(fileInfo=>fileInfo.Length);
案例“扩展”
返回新的FileInfoComparer(fileInfo=>fileInfo.Extension);
...
违约:
抛出新的NotSupportedException(“不支持按此属性排序”);
//例如:属性名称“目录”“存在”
}
}
专用文件信息比较器(Func键选择器)
{
this.keySelector=keySelector;
}
专用只读Func键选择器;
private readonly IComparer keycomarer=Comparer.Default;
公共整数比较(FileInfo x,FileInfo y)
{
//TODO:决定当x或y为空时该怎么办。异常?排序顺序的第一个还是最后一个?
返回keycomarer.Compare(this.keySelector(x),this.keySelector(y));
}
}
我创建了一个私有构造函数,因此只有Create函数才能创建这个比较器

用法:

var comparer=FileInfoComparer.Create(“长度”); DirectoryInfo directory=新的DirectoryInfo(directoryPath); var orderedFiles=directory.EnumerateFiles.Orderby(file=>file,comparer)

propertyInfo.GetValue(新文件信息(f),null)
-您正在读取
f