C# 将IEnumerable转换为List以符合方法签名

C# 将IEnumerable转换为List以符合方法签名,c#,list,ienumerable,C#,List,Ienumerable,我有一个下面的代码,返回所有文件的列表。它读取文件夹和子文件夹中的所有文件,并将其作为列表返回给用户 我有两个案件在下面的代码 案例1: 如果IS\u PROC为true,则我以不同的方式获取文件,然后将其返回给用户 在本例中,我有一个IEnumerable查询,我正在将其转换回列表,因为我的方法签名是IList。不确定将IEnumerable转换为List是否是个好主意 案例2: 如果IS\u PROC为false,则我以另一种方式获取文件,然后将其返回给用户 在这种情况下,我只是有一个

我有一个下面的代码,返回所有文件的列表。它读取文件夹和子文件夹中的所有文件,并将其作为列表返回给用户

我有两个案件在下面的代码

案例1:

  • 如果
    IS\u PROC
    为true,则我以不同的方式获取
    文件
    ,然后将其返回给用户
  • 在本例中,我有一个
    IEnumerable
    查询,我正在将其转换回列表,因为我的方法签名是
    IList
    。不确定将
    IEnumerable
    转换为
    List
    是否是个好主意
案例2:

  • 如果
    IS\u PROC
    为false,则我以另一种方式获取
    文件
    ,然后将其返回给用户
  • 在这种情况下,我只是有一个列表,所以我只是返回它
下面是我的代码:

private IList<string> ReadFiles(string path)
{
    var files = new List<string>();
    try
    {
        if (IS_PROC)
        {
            // case 1:
            IEnumerable<string> query =
                from directory in System.IO.Directory.EnumerateDirectories(path)
                let dev = System.IO.Path.Combine(directory, "dev")
                from file in System.IO.Directory.EnumerateFiles(directory)
                let fi = new System.IO.FileInfo(file)
                let dev_file = System.IO.Path.Combine(dev, fi.Name)
                select System.IO.File.Exists(dev_file) ? dev_file : file;
            // is this the right way to do it?
            return (!query.Any()) ? files : query.ToList();
        }
        // case 2:
        var lclJsonFiles = Directory.GetFiles(path, "*.json", SearchOption.AllDirectories);
        var lclTxtFiles = Directory.GetFiles(path, "*.txt", SearchOption.AllDirectories);
        files.AddRange(lclJsonFiles);
        files.AddRange(lclJsonFiles);
    }
    catch (Exception ex)
    {
        // log error here
    }
    return files;
}
私有IList读取文件(字符串路径)
{
var files=新列表();
尝试
{
if(IS_PROC)
{
//案例1:
IEnumerable查询=
来自System.IO.directory.EnumerateDirectory(路径)中的目录
让dev=System.IO.Path.Combine(目录“dev”)
从System.IO.Directory.EnumerateFiles(目录)中的文件
设fi=new System.IO.FileInfo(文件)
让dev_file=System.IO.Path.Combine(dev,fi.Name)
选择System.IO.File.Exists(dev_File)?dev_File:File;
//这样做对吗?
返回(!query.Any())?文件:query.ToList();
}
//案例2:
var lclJsonFiles=Directory.GetFiles(路径“*.json”、SearchOption.AllDirectories);
var lclTxtFiles=Directory.GetFiles(路径“*.txt”,SearchOption.AllDirectories);
files.AddRange(lclJsonFiles);
files.AddRange(lclJsonFiles);
}
捕获(例外情况除外)
{
//此处记录错误
}
归还文件;
}
所以我的问题是-

  • 考虑到我在这两种情况下所做的工作,从我的方法返回
    IList
    有意义吗
  • 另外,我的一个case返回
    IEnumerable
    ,另一个case返回
    List
    ,因此为了使其与我的方法签名兼容,我将
    IEnumerable
    转换为Case1中的List?这是将
    IEnumerable
    转换为列表的正确方法吗
  • 有没有更好的方法来编写上述方法

您可以用任何一种方式编写方法,这实际上取决于您想做什么。如果要返回一个
IEnumerable
,只需停止
ToList()
调用,它就可以工作了。您还可以将
GetFiles
替换为
Directory.EnumerateFiles
,因为它还返回一个
IEnumerable

private IEnumerable<string> ReadFiles(string path)
{
    try
    {
        return IS_PROC
            ? (from directory in Directory.EnumerateDirectories(path)
                let dev = Path.Combine(directory, "dev")
                from file in Directory.EnumerateFiles(directory)
                let fi = new FileInfo(file)
                let devFile = Path.Combine(dev, fi.Name)
                select File.Exists(devFile) ? devFile : file)
            : Directory
                .EnumerateFiles(path, "*.json", SearchOption.AllDirectories)
                .Union(Directory.EnumerateFiles(path, "*.txt", SearchOption.AllDirectories));
    }
    catch (Exception ex)
    {
        // log error here
        return new List<string>();
    }
}
私有IEnumerable可读文件(字符串路径)
{
尝试
{
返回是_PROC
?(来自目录中的目录。枚举目录(路径)
让dev=Path.Combine(目录“dev”)
从目录中的文件。枚举文件(目录)
让fi=新文件信息(文件)
让devFile=Path.Combine(dev,fi.Name)
选择File.Exists(devFile)?devFile:File)
:目录
.EnumerateFiles(路径“*.json”、SearchOption.AllDirectories)
.Union(Directory.EnumerateFiles(路径“*.txt”、SearchOption.AllDirectories));
}
捕获(例外情况除外)
{
//此处记录错误
返回新列表();
}
}

否则,您可以在返回值的末尾添加
.ToList()
,并返回
IList
。请注意,
List
实现了
IEnumerable
,因此在任何一种情况下都可以返回
List

如果不执行
.ToList()
在案例1中,查询不会被枚举,因此求值将由调用方完成(以及调用方代码中引发的异常)。但是案例1和案例2完全不同,您应该使用两个单独的方法EAH即使我使用两个单独的方法,一个将返回IEnumerable,另一个将返回IList,因此在调用方端,我期望列表,那么我是否应该将调用方端更改为期望IEnumerable?如果要返回
IEnumerable
,然后可以
返回查询
返回Directory.EnumerateFiles(路径“*.json”、SearchOption.AllDirectories).Union(Directory.EnumerateFiles(路径“*.txt”、SearchOption.AllDirectories))在第二种情况下。但是正如卡米洛指出的那样,
IEnumerable
的行为不同于
列表
:在访问集合之前(调用
.ToList()
时)不会进行评估,这将发生在调用方。我明白了,如果我想在案例1中返回
IList
,那么我所做的是对的吗<代码>返回(!query.Any())?文件:query.ToList()为什么不总是返回
query.ToList()
<代码>文件
在这一点上也是一个空列表。我看这看起来很干净。因此,如果我决定在末尾添加
.ToList()
,那么当它在这两个案例中都找不到任何文件时会发生什么情况-它会在null对象上引发异常调用
.ToList()
?您指的是什么
null
对象?我不相信这些语句中的任何一个都会返回
null
,对吗?另外,在原始代码中,您正在调用
。如果
query
null
,则会抛出
query
上的任何
,因此我认为您不必担心它!这里的
catch
几乎没有任何用处(除了对
EnumerateDirectories
的初始检查),给人一种错误的印象,即IO错误会被捕获。我将完全取消try-catch,这样调用方就可以明确地处理异常。好的一点是,他们可以进行日志记录,然后通过