如何创建一个通用函数,使用现有的重载映射函数将ClassA列表转换为ClassB.(C#)

本文关键字:重载 ClassA 映射函数 转换 ClassB 列表 创建 何创建 一个 函数 | 更新日期: 2023-09-27 18:24:07

我有许多重载方法,用于将对象从一个类转换到另一个类。例如

    private ClassB MapClass(ClassA inputClass)
    {
        ClassB outputClass = new ClassB();
        outputClass.PropA = inputClass.PropA;
        outputClass.PropB = inputClass.PropB;
        ...
        return outputClass;
    }
    private ClassD MapClass(ClassC inputClass)
    {
        ...
    }

我的问题是,有时我可能有一个ClassA列表,我想将其转换为ClassB列表。有没有一种方法可以让我写一个通用方法,接受ClassA的列表,调用适当的转换函数并返回ClassB的列表?当然,我可以简单地为每个接受列表的方法编写一个额外的转换方法,但由于大约有20个这样的方法,如果可能的话,我希望避免代码重复。

为了澄清,我正在尝试做一些类似的事情:

    private List<T1> MapModelList<T1, T2>(List<T2> inputList)
    {
        List<T1> outputList = new List<T1>();
        foreach (T2 input in inputList)
        {
            T1 output = new T1();
            output = MapClass(input);
            outputList.Add(output);
        }
        return outputList;
    }

这显然不起作用。有没有办法做到这一点,或者有更好的方法?

如何创建一个通用函数,使用现有的重载映射函数将ClassA列表转换为ClassB.(C#)

您必须将一个参数传递给作为适当转换方法委托的方法。

private List<TOutput> MapModelList<TInput, TOutput>(List<TInput> input, Func<TInput, TOutput> mapper)
{
    return input.Select(mapper).ToList();
}

示例用法:

var bList = MapModelList(aList, MapClass);

您可以使用创建T2的新实例

System.Activator.CreateInstance<T2>()

只需添加一个新的约束:

where T2 : new()

或将映射函数作为视差计传递:

private List<T1> MapModelList<T1, T2>(List<T2> inputList, Func<T2> map)

您可以更改方法以获取转换函数。

private List<T1> MapModelList<T1, T2>(List<T2> inputList, Func<T2, T1> convert) {
    return inputList.Select(i => convert(i)).ToList();
}

此外,如果您让它们都实现相同的接口,那么您只需要编写一个方法。

interface ISomeInterface {
    PropA { get; set; }
    PropB { get; set; }
}
private T MapClass<T>(ISomeInterface inputClass)
    where T : ISomeInterface, new()
{
    T outputClass = new T();
    outputClass.PropA = inputClass.PropA;
    outputClass.PropB = inputClass.PropB;
    ...
    return outputClass;
}
public class MyBaseClass
{
    public virtual void Map<T>(T obj)
    {
        // Override in specific class
        //Use PropertyInfo to map the properties of the class
    }
}
public class MyFirstClass : MyBaseClass
{
}
public class MySecondClass : MyBaseClass
{
}
public class MyClassFactory
{
    public T CreateMyClass<T>() where T : MyBaseClass, new()
    {
        return new T();
    }
    public List<T1> MapClass<T1, T2>(List<T2> inputList) where T1 : MyBaseClass, new()
    {
        List<T1> outputList = new List<T1>();
        foreach (T2 input in inputList)
        {
            T1 output = CreateMyClass<T1>();
            output.Map(input);
            outputList.Add(output);
        }
        return outputList;
    }
}

你可以试试这样的东西。

并且可以使用的是Main作为

class Program
{
    static void Main(string[] args)
    {
        List<MyFirstClass> firstClasses = new List<MyFirstClass>();
        MyFirstClass obj1 = new MyFirstClass();
        MyFirstClass obj2 = new MyFirstClass();
        MyFirstClass obj3 = new MyFirstClass();
        MyFirstClass obj4 = new MyFirstClass();
        firstClasses.Add(obj1);
        firstClasses.Add(obj2);
        firstClasses.Add(obj3);
        firstClasses.Add(obj4);
        var secondClasses = new MyClassFactory().MapClass<MySecondClass, MyFirstClass>(firstClasses);
    }
}