Is it possible to create a List using anonymous types on both sides (input and output) of the declaration?

StackOverflow https://stackoverflow.com/questions/17676139

Domanda

Is it possible to create a list using anonymous types on both sides (input and output) of the declaration?

I would like to do something like this:

List<Class1> list = getList<Class1>(List<Class2> list2);

...using a method declared something like this:

public static List<T1> getList<T1>(List<T2> list2)
{
    List<T1> list = new List<T1>();
    foreach (var item in list2) {
        list.Add(new T1(item));                
    }
    return list;
}

Basically, I just want to convert a list containing class2 items to a new list containing class1 items. My idea was to set up a constructor in Class1, doing the convert job (from class1 to class2). But there might be better ways of doing such a thing. These are my classes:

public class Class2
{
    string prop1 { get; set; }
    string prop2 { get; set; }
}

public class Class1
{
    string member1 { get; set; }
    string member2 { get; set; }

    //constructor: 'converts' class1 in class2
    public Class1(Class2 class2)
    {
        this.member1 = Util.getThisAndThat(class2.prop1);
        this.member2 = Util.doBunchOfStuff(class2.prop2);
    }
}

Any help appreciated :)

È stato utile?

Soluzione

Another answer mentioned AutoMapper, but I would use it directly.

Mapper.CreateMap<Class1, Class2>()
      .ForMember(dest => dest.member1,
                 opt => opt.MapFrom(src => Util.getThisAndThat(src.prop1)))
      .ForMember(dest => dest.member2,
                 opt => opt.MapFrom(src => Util.doBunchOfStuff(src.prop2)));

public static List<T1> getList<T1>(List<T2> list2)
{
    return Mapper.Map<List<T2>, List<T1>>(list2);
}

Altri suggerimenti

You can do something like below, if it works. For each different type like Class1 and Class2 you need to implement the interface. But what you are actually looking for seems like AutoMapper

public interface ILoadable<T> 
{
    void LoadFrom(T other);
}

public class Class1 : ILoadable<Class2>
{
    public void LoadFrom(Class2 other) 
    {
        // Do property mapping here
    }
}

public static List<T1> GetList<T1, T2>(List<T2> list2) where T1 : ILoadable<T2>, new()
{
    List<T1> list = new List<T1>();
    foreach (var item in list2) {
        T1 t1 = new T1();
        t1.LoadFrom(item);
        list.Add(t1);                
    }
    return list;
}

You can just write:

List<Class1> list1 = list2.Select(class2 => new Class1(class2)).ToList();

But for it to work, Class1 must have a constructor that takes Class2 as a parameter, which is not great in my opinion.

I would write a separate static method which converts a Class2 instance to a Class1 instance:

public static Class1 ToClass1(Class2 class2)
{
  //return a Class1 instance
}

And do:

List<Class1> list1 = list2.Select(class2 => ToClass1(class2)).ToList();

If you're happy to have some coupling between both classes, you can add a conversion operator to one of them and do:

List<Class1> list1 = list2.Cast<Class1>().ToList();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top