C# 尝试定义类似于List.ConvertAll(TOutput)的方法

C# 尝试定义类似于List.ConvertAll(TOutput)的方法,c#,linq,C#,Linq,我想定义一个名为MergeAll的List扩展方法。我希望它从一种类型的列表中获取元素,并生成另一种类型的列表。我为转换器的合并等效项定义了一个委托 public delegate TOutput Merger<in TInput, out TOutput>(TInput input) 但我一辈子都搞不懂扩展方法的语法。我的尝试是: public static List<TOutput> MergeAll<TOutput>(this List<TOut

我想定义一个名为MergeAll的List扩展方法。我希望它从一种类型的列表中获取元素,并生成另一种类型的列表。我为转换器的合并等效项定义了一个委托

public delegate TOutput Merger<in TInput, out TOutput>(TInput input)
但我一辈子都搞不懂扩展方法的语法。我的尝试是:

public static List<TOutput> MergeAll<TOutput>(this List<TOutput> output,
    Merger<TOutput, TInput> merger)

那么,MergeAll的主体应该是什么样子呢?

您正在尝试的被称为投影

为了实现这一点,.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
    });

}
您需要将TInput添加到MergeAll,并将第一个参数更改为List,第二个参数更改为Func


自定义方法和内置Select之间的区别是什么?您可以先查看Microsoft实现:,但不确定为什么转换器不能仅与内置ConvertAll方法一起工作?ConvertAll的区别是什么,它返回一个包含已转换元素的新列表?这是一种很好的思考方式。感谢@Aydin Adn在您的帖子中提供的所有信息。我想要实现的微妙之处是,对于要扩展的IEnumerable中的每个类型为A的对象,我想要将对象类型为B的一些字段作为函数参数传递,以更新类型A中的一些字段。因此,我的MergeAll。这是一个很大的帮助。
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;
}
List<double> doubles = new List<double> { 1.3, 2.2, 3.5, 4.7 };
List<int> ints = doubles.MergeAll(doubleParam => Convert.ToInt32(doubleParam)).ToList();