尝试定义类似于List <t> .ConvertAll(TOutput)的方法

时间:2015-05-09 19:04:54

标签: c# linq

我想定义一个名为List<T>的{​​{1}}扩展方法。我希望它从一个类型的列表中获取元素并生成另一个类型的列表。我有一个为MergeAll()(相当于转换器)

定义的委托
Merger

但不能为我的生活弄清楚扩展方法的语法。我的尝试是:

public delegate TOutput Merger<in TInput, out TOutput>(TInput input)

然后,public static List<TOutput> MergeAll<TOutput>(this List<TOutput> output, Merger<TOutput, TInput> merger) 的身体应该是什么样的?

2 个答案:

答案 0 :(得分:5)

您尝试的内容称为projection

.NET Framework中已包含一个扩展方法来实现此目的。 IEnumerable.Select,您可以按照以下方式使用它。

void Main()
{
    List<Foo> foos = new List<Foo> 
    { 
        new Foo { Name = "Fu" }, 
        new Foo { Name = "Foe" }, 
        new Foo { Name = "Thumb" } 
    };

    IEnumerable<Bar> bars = foos.Select(foo => new Bar
    {
        BarId = foo.Id,
        Name  = foo.Name
    });

}

public class Foo 
{
    public Foo() { Id = Guid.NewGuid().ToString(); }

    public string Id { get; set; }
    public string Name { get; set; }
}

public class Bar
{
    public Bar()
    {
        this.BarId = Guid.NewGuid().ToString();
        this.TimeCreated = DateTime.UtcNow;
    }

    public string BarId { get; set; }
    public string Name { get; set; }
    public DateTime TimeCreated { get; set; }
}

Foo to Bar

如何实施....

如果您想为了学习而自己实施自定义解决方案,那么您可以这样做:

public static class Extensions
{
    public static IEnumerable<TDestination> ConvertTo<TFrom, TDestination>(this IEnumerable<TFrom> fromCollection, Func<TFrom, TDestination> expression)
    {
        List<TDestination> destinationList = new List<TDestination>();
        foreach (var element in fromCollection)
        {
            destinationList.Add(expression.Invoke(element));
        }

        return destinationList;

    }
}

void Main()
{
    List<Foo> foos = new List<Foo>
    {
        new Foo { Name = "Fu" },
        new Foo { Name = "Foe" },
        new Foo { Name = "Thumb" }
    };

    IEnumerable<Bar> customBars = foos.ConvertTo(foo => new Bar
    {
        BarId = foo.Id,
        Name = foo.Name
    });

}

答案 1 :(得分:4)

您需要将TInput添加到MergeAll<TInput, TOutput>,然后将第一个参数更改为List<TInput>,将第二个更改为Func<TInput, TOutput>

public static List<TOutput> MergeAll<TInput, TOutput>(this List<TInput> inputs,
                                        Func<TInput, TOutput> merger)
{
    var outputs = new List<TOutput>();
    foreach (var input in inputs)
    {
        outputs.Add(merger(input));
    }
    return outputs;
}

double转换为int的简单用法如下所示:

List<double> doubles = new List<double> { 1.3, 2.2, 3.5, 4.7 };
List<int> ints = doubles.MergeAll(doubleParam => Convert.ToInt32(doubleParam)).ToList();