0

There are a lot of methods to convert a string/List to a list of something else.

Out of curiosity I can't find if there is a way to do it this way

Directory.EnumerateFiles(@"C:\Drivers").ToList<FileInfo>();

Or Either

new List<string>(Directory.EnumerateFiles(@"C:\Drivers")).Cast<FileInfo>();`

`

As fileinfo takes FileInfo(path) as parameter, there is a way to do like this or a short oneliner which doesn't involve linq Select(x => new FileInfo(x) or something like that?

Liquid Core
  • 1
  • 6
  • 27
  • 52

1 Answers1

1

There is nothing built-in that does this (binding to a constructor). I am not sure why you would want to avoid Select(x => new FileInfo(x)). However, you could if you wanted to define an extension method such as the below Construct to perform the binding:

    static void Main(string[] args)
    {
        const string path = "d:\\";
        var results = Directory.EnumerateFiles(path).Construct<string, FileInfo>();
    }

    private static ConcurrentDictionary<Type, object> constructors = new ConcurrentDictionary<Type, object>();

    private static IEnumerable<TOutput> Construct<TInput, TOutput>(this IEnumerable<TInput> input)
    {
        var constructor = constructors.GetOrAdd(typeof(TOutput), (Type type) =>
        {
            var parameterExpression = Expression.Parameter(typeof(TInput));
            var matchingConstructor = typeof(TOutput).GetConstructor(new[] { typeof(TInput) });
            var expression = Expression.Lambda<Func<TInput, TOutput>>(Expression.New(matchingConstructor, parameterExpression), parameterExpression);
            return (object)expression.Compile();
        });

        return input.Select(x => ((Func<TInput,TOutput>)constructor)(x));
    }
Jason
  • 369
  • 1
  • 4