【问题标题】:Parametrized List<K>.Cast<T> with parametrized initialization具有参数化初始化的参数化 List<K>.Cast<T>
【发布时间】:2018-03-15 17:56:25
【问题描述】:

有很多方法可以将字符串/列表转换为其他内容的列表。

出于好奇,我不知道是否有办法这样做

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

要么

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

`

由于 fileinfo 将 FileInfo(path) 作为参数,有一种方法可以做到这一点或一个不涉及 linq Select(x => new FileInfo(x) 或类似的东西的短单行器?

【问题讨论】:

    标签: linq generics casting system.io.fileinfo


    【解决方案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));
        }
    

    【讨论】:

    • 谢谢 :) 如果没有,我会使用 select,就像我问的那样
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-25
    • 2015-11-23
    • 1970-01-01
    相关资源
    最近更新 更多