带有参数化初始化的参数化列表<k> .Cast <t>

时间:2018-03-15 17:56:26

标签: linq generics casting system.io.fileinfo

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

出于好奇,我找不到是否有办法这样做

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

或者

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

`

由于fileinfo将FileInfo(path)作为参数,有一种方法可以像这样做或短的oneliner,它不涉及linq Select(x =&gt; new FileInfo(x)或类似的东西?

1 个答案:

答案 0 :(得分:1)

没有内置功能(绑定到构造函数)。我不确定你为什么要避免选择(x =&gt;新的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));
    }