Search code examples
c#winformsfileinfosystem.io.fileinfo

Using linq with if-query


i have the following code which groups a list of FileInfos:

            var group_infos =
            from info in fileInfos
            where info.Length < 1024 * 1024
            group info by info.Name into g
            where g.Count() > 1
            orderby g.Count() descending, g.Key
            select g;

Now i want to do an if-query on the group-clausel. Maybe with help of a string

string groupClausel = "Name";

or enum:

    public enum FilterMethod
    {
        Directory,
        CreationTime,
        DirectoryName,
        Extension,
        Length, 
        Name
    }

But i dont know how to check the string or enum in group-clausel.. I know there s a syntax like

    group info by (groupClausel == "Extension" ? info.Extension : info.Name) into g

But this let me just select on two attributes...

Do you people have an idea?


Solution

  • You could use method syntax instead of query syntax here, it will be more maintainable and readable in my oppinion.

    For example, you could make a method which returns group by key selector function:

    private Func<FileInfo, object> GetGroupByKeySelector(FilterMethod filterMethod)
    {
        Func<FileInfo, object> keySelector = null;
        switch (filterMethod)
        {
            case FilterMethod.Directory:
                keySelector = f => f.Directory;
                break;
    
            case FilterMethod.CreationTime:
                keySelector = f => f.CreationTime;
                break;
    
            case FilterMethod.DirectoryName:
                keySelector = f => f.DirectoryName;
                break;
    
            case FilterMethod.Extension:
                keySelector = f => f.Extension;
                break;
    
            case FilterMethod.Length:
                keySelector = f => f.Extension;
                break;
    
            default:
                keySelector = f => f.Name;
                break;
        }
        return keySelector;
    }
    

    And then you can use it as described below:

    FilterMethod prop = FilterMethod.CreationTime;
    var groupInfos = fileInfos
        .Where(f => f.Length < 1024 * 1024)
        .GroupBy(GetGroupByKeySelector(prop))
        .Where(g => g.Count() > 1)
        .OrderByDescending(g => g.Count())
        .OrderBy(g => g.Key)
        .Select(g => g);
    

    Additionaly, you can use System.Net.Reflection library to avoid switch-case inside GetGroupByKeySelector method if your enum reflects FileInfo property names.