我想定义一个名为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)
的身体应该是什么样的?
答案 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; }
}
如果您想为了学习而自己实施自定义解决方案,那么您可以这样做:
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();