Asbjoedt
Asbjoedt

Reputation: 89

Best way to return an enumeration of files with certain extensions

I need to create an enumeration of spreadsheets based on their file extensions, I need two options either recursive and no recursive and I need to return the enumeration from my enumeration. I have this code

using System;
using System.IO;
using System.IO.Enumeration;
using System.Collections.Generic;
using Enumerate_org = System.Collections.Generic.IEnumerable<string>;

        public IEnumerable<T> Enumerate_Original<T>(string argument1, string argument3)
        {
            Enumerate_org<T> org_enumeration = new Enumerate_org<T>();

            // Recurse enumeration of original spreadsheets from input directory
            if (argument3 == "Recurse=Yes")
            {
                org_enumeration = Directory.EnumerateFiles(argument1, "*.*", SearchOption.AllDirectories)
                .Where(file => file.EndsWith(".fods") || file.EndsWith(".ods") || file.EndsWith(".ots") || file.EndsWith("xla") || file.EndsWith(".xls") || file.EndsWith(".xls") || file.EndsWith(".xlt") || file.EndsWith(".xlam") || file.EndsWith(".xlsb") || file.EndsWith(".xlsm") || file.EndsWith(".xlsx") || file.EndsWith(".xltm") || file.EndsWith(".xltx"))
                .ToList();

                return org_enumeration;
            }

            // No recurse enumeration
            else
            {
                org_enumeration = Directory.EnumerateFiles(argument1, "*.*", SearchOption.TopDirectoryOnly)
                .Where(file => file.EndsWith(".fods") || file.EndsWith(".ods") || file.EndsWith(".ots") || file.EndsWith("xla") || file.EndsWith(".xls") || file.EndsWith(".xls") || file.EndsWith(".xlt") || file.EndsWith(".xlam") || file.EndsWith(".xlsb") || file.EndsWith(".xlsm") || file.EndsWith(".xlsx") || file.EndsWith(".xltm") || file.EndsWith(".xltx"))
                .ToList();

                return org_enumeration;
            }

        }

But I get the error

The using alias 'Enumerate_org' cannot be used with type arguments
  1. What am I doing wrong?

  2. I have an array of file extensions that are accepted. How to replace

file.EndsWith("a specific extension")

with the same search but trying to match any of the entries in the extensions array?

Upvotes: 0

Views: 286

Answers (3)

Asbjoedt
Asbjoedt

Reputation: 89

AlanK got me on the right track and I turned the IEnumerable into a list instead. The code is now:

public List<string> Enumerate_Original(string argument1, string argument3)
{    
    var org_enumeration = new List<string>();

    // Recurse enumeration of original spreadsheets from input directory
    if (argument3 == "Recurse=Yes")
    {
        org_enumeration = (List<string>)Directory.EnumerateFiles(argument1, "*.*", SearchOption.AllDirectories)
            .Where(file => file_format.Contains(Path.GetExtension(file)))
            .ToList();

        return org_enumeration;
    }

    // No recurse enumeration
    else
    {
        org_enumeration = (List<string>)Directory.EnumerateFiles(argument1, "*.*", SearchOption.TopDirectoryOnly)
           .Where(file => file_format.Contains(Path.GetExtension(file)))
           .ToList();

        return org_enumeration;
    }
}

Upvotes: 0

AlanK
AlanK

Reputation: 1951

The error is because you declare a type alias for a closed (specific, resolved) type <string> in using Enumerate_org = System.Collections.Generic.IEnumerable<string>;, then attempt to use it new Enumerate_org<T>();

This is wrong in two ways - you cannot re-type or "untype" (go back to <T> AND you can't instantiate an interface IEnumerable.

You could have used the alias and said Enumerate_org org_enumeration = new List<string>(); but that makes the type alias redundant (so get rid of it and just say using System.Collections.Generic;).

Then...

var org_enumeration = new List<string>(); // question #1, instead of new System.Collections.Generic.List<string>();
:
... Where(file => ExtensionsList.Contains(Path.GetExtension(file)))... // question #2

Do return IEnumerable<string> and do not call .ToList() on your enumerables before returning. Here is some reading: C#: IEnumerable, yield return, and lazy evaluation

Upvotes: 2

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186698

I suggest using Path class in order to obtain extension:

// Since we enumerate files' names, we return IEnumerable<string>
public static IEnumerable<string> Enumerate_Original(string argument1,
                                                     string argument3) {
  var extensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {
    //TODO: add all required extensions here
    ".fods",
    ".ods",
  };

  return Directory
    .EnumerateFiles(argument1, 
                    "*.*", 
                    argument3 == "Recurse=Yes" 
                      ? SearchOption.AllDirectories 
                      : SearchOption.TopDirectoryOnly)
    .Where(file => extensions.Contains(Path.GetExtension(file)));
}

Upvotes: 2

Related Questions