Параметризованный список<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));
}