Параметризованный список<K>.Cast<T> с параметризованной инициализацией

Есть много методов для преобразования строки / списка в список чего-то еще.

Из любопытства я не могу найти, есть ли способ сделать это таким образом

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

Или другое

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

`

Поскольку fileinfo принимает FileInfo (путь) в качестве параметра, есть способ сделать это или короткий oneliner, который не включает linq Select(x => new FileInfo(x) или что-то в этом роде?

1 ответ

Нет ничего встроенного, что делает это (привязка к конструктору). Я не уверен, почему вы хотели бы избежать Select(x => new FileInfo(x)). Однако вы можете, если хотите определить метод расширения, такой как приведенный ниже Construct, для выполнения привязки:

    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));
    }
Другие вопросы по тегам