2

I'm trying to learn C# and I'm a bit stuck with a problem. Probably obvious for most of experienced programmers, but not for me :(

I'm trying to write a class that is supposed to have 3 constructor overloads:

  • I only specify the folder.
  • I specify the folder and the file type (file extension).
  • I specify the folder, file type and yes/no for sub folder search.

Depending on the user specification the class returns a List.

So I wrote the following code:

public class SearchForFiles
{
    private readonly List<string> _filePath = new List<string>();
    private readonly List<string> _fileType = new List<string>();
    private readonly bool _searchSubFolder = false;
    private SearchOption _searchOption = SearchOption.TopDirectoryOnly;
    private readonly IEnumerable<string> _searchForFiles = null;

   /// <summary>
    /// Searching all the files in the specified folder.
    /// </summary>
    /// <param name="searchFolder">Specify folder for file search</param>
    public SearchForFiles(string searchFolder)
    {
        _filePath.Add(searchFolder);
        _fileType.Add(".*");
        FindFiles(_filePath, _fileType, false);
    }

    /// <summary>
    /// Searching all the files with the specified file extension in the specified folder.
    /// </summary>
    /// <param name="searchFolder">Specify folder for file search</param>
    /// <param name="fileType">Specify extension of the file search</param>
    public SearchForFiles(string searchFolder, string fileType)
        : this(searchFolder)
    {
        _fileType.Add(fileType);
        FindFiles(_filePath, _fileType, false);
    }

    public SearchForFiles(List<string> searchFolder, List<string> fileType, bool searchSubFolder)
        : this(searchFolder, fileType)
    {
        _searchSubFolder = searchSubFolder;
        FindFiles(_filePath, _fileType, _searchSubFolder);
    }

It's the third overload that's the problem, I don't understand why the second overload is all right but not the third.

If anybody could give me some help that would be great.

Here is the updated Code that works:

/// <summary>
/// Returning a list of files depending on the user choices.
/// </summary>
public class SearchForFiles
{
    private readonly List<string> _filePath = new List<string>();
    private readonly List<string> _fileType = new List<string>();
    private readonly bool _searchSubFolder = false;
    private SearchOption _searchOption = SearchOption.TopDirectoryOnly;
    private IEnumerable<string> _searchForFiles = null;

    /// <summary>
    /// Searching all the files with the specified file extension(s) in the specified folder(s) and sub folder(s) if wanted.
    /// </summary>
    /// <param name="searchFolder">Specify folder(s) for file(s) search</param>
    /// <param name="fileType">Specify file extension(s) for the search</param>
    /// <param name="searchSubFolder">Specify if you want to search in sub folder(s)</param>
    public SearchForFiles(List<string> searchFolder, List<string> fileType, bool searchSubFolder)
    {
        _filePath = searchFolder;
        _fileType = fileType;
        _searchSubFolder = searchSubFolder;
        FindFiles();
    }

    /// <summary>
    /// Searching all the files with the specified file extension in the specified folder.
    /// </summary>
    /// <param name="searchFolder">Specify folder for file search</param>
    /// <param name="fileType">Specify file extension for the search</param>
    public SearchForFiles(string searchFolder, string fileType)
        : this(new List<string>() {searchFolder}, new List<string>() {fileType}, false)
    {

    }

    /// <summary>
    /// Searching all the files in the specified folder.
    /// </summary>
    /// <param name="searchFolder">Specify folder for file search</param>
    public SearchForFiles(string searchFolder)
        : this(new List<string>() {searchFolder}, new List<string>(), false)
    {

    }

    private List<string> FindFiles()
    {
        var findFiles = new List<string>();

        if (_searchSubFolder == true)
            _searchOption = SearchOption.AllDirectories;

        foreach (var filePath in _filePath)
        {
            if (_fileType.Count == 0)
            {
                _searchForFiles = Directory.EnumerateFiles(filePath, "*.*", _searchOption);
            }
            else
            {
                _searchForFiles = Directory.EnumerateFiles(filePath, "*.*", _searchOption).Where(e => _fileType.Contains(new FileInfo(e).Extension, StringComparer.OrdinalIgnoreCase));
            }

            foreach (var file in _searchForFiles)
            {
                findFiles.Add(file);
            }
        }

        return findFiles;
    }
}

Thanks a lot for all the hints and answers :)

5
  • Because your third overload constructor parameter is List<string> but the second overload constructor need to pass string. the type is different. Commented Sep 29, 2018 at 21:03
  • The solution is fairly simple. You give the overload a List, you need to pass it a string. Commented Sep 29, 2018 at 21:05
  • 2
    Let's ignore the third one for now. Your first two should be reversed; the one parameter constructor should invoke the two parameter constructor, not the other way around. As it is, if someone invokes the two argument one, it will invoke the one arg one (adding *.* as a file type) and then add the file type the caller specified. Instead, have one one arg version invoke the two are version with the default ‘*.*`. You might consider just an optional arg instead. You didn't mention the the error you are getting, but I'm guessing it has to do with passing a list of string where a string is expec Commented Sep 29, 2018 at 21:15
  • 3
    In general, you should rearrange everything. Get rid of all the initializations at the top, implement the 3 param constructor fully, then have the two and one param versions call up to the next one up, passing defaults where applicable. Why do you call FindFiles in the constructors, does it change the object's state, or does it return the files it finds. If the latter, it belongs in an instance method. Finally, you don't overload constructors, a class can just have more than one declared. Commented Sep 29, 2018 at 21:23
  • Your current setup would call FindFiles() 3 times when you use the third constructor. Commented Sep 29, 2018 at 21:31

1 Answer 1

3

@CrazyNoun, As @D-Shih said you must correct the type mismatch problem at the first. and about Constructors: Constructor Overloading maybe implemented to reach to a single goal in multiple manners (e.g MessageBox.Show() Overloads in windows form) and it maybe implemented to reach to multiple goals through multiple manners (e.g Convert.ToString() Overloads).

You want to reach to a Single goal. in this way we should define the Defaults. Your declarations are in a Reverse Order. actually you must define something like this:

public class SearchForFiles
{
     public SearchForFile(List<string> searchFolder, List<string> fileType, bool searchSubFolder)
     {
         _searchSubFolder = searchSubFolder;
         FindFiles(searchFolder, fileType, searchSubFolder);
     }

     public SearchForFiles(string searchFolder, string fileType):this(new List<string>(){searchFolder}, new List<string>(){fileType}, false)
     {

     }

     public SearchForFiles(string searchFolder):this(new List<string>(){searchFolder}, new List<string>(), false)
     {

     }

I have added List support to the constructors. so if you wanted to generalize it's needed. as you can see there is no need to write a body for each Constructor Signiture. Actually the other constructors will make some input parameters for the main Constructor and they will call it to run by putting the values and adding some defaults for faster usage.

Sign up to request clarification or add additional context in comments.

2 Comments

I had a thinking problem about the implementation order of the constructor overload. Thank you for clarifying this point.
This is programming world and its our everyday challenge ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.