Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# Generics new() constraints with type: (new(T))

I'm building a little helper to turn EF4 objects to POCOs. (I know there is AutoMapper, but I'm having a c# dilemma at this time)

How can I make this work (the where P: new(E) is not legal I wish to make sure the P (POCO) class as a constructor that takes the E class (hence handling the transformation)

How can I make this work ?

How can I make a generic function in C# that can take a new(type) constraint ?

   public static List<P> ListConvert<E, P>(List<E> efList) where P: new(E)
    {
        List<P> pList = new List<P>();

        foreach (E item in efList)
        {
            P myItem = new P(item);
            pList.Add(myItem);
        }
        return pList;
like image 612
Dani Avatar asked Jan 13 '11 17:01

Dani


3 Answers

There's no such constraint. What you can do is have an extra parameter:

public static List<P> ListConvert<E, P>(List<E> efList, Func<E, P> func)

That way it isn't required to be a constructor, but you can pass in a delegate which calls the constructor:

ListConvert(list, x => new Foo(x))

I have a blue-sky idea which would enable constructor constraints, called "static interfaces" - these would only be useful for generic constraints, but would also enable some operator use cases.

like image 128
Jon Skeet Avatar answered Oct 12 '22 23:10

Jon Skeet


This is not possible. The new constraint only allows you to create objects via a public parameterless constructor.

like image 42
Michael Goldshteyn Avatar answered Oct 13 '22 01:10

Michael Goldshteyn


There's no such thing as P : new(E), but you could have the caller supply a delegate that knows how to construct a P given an E:

public static List<P> ListConvert<E, P>(List<E> efList, Func<E, P> converter)
{
    List<P> pList = new List<P>();

    foreach (E item in efList)
    {
        P myItem = converter(item);
        pList.Add(myItem);
    }
    return pList;
}

However, if you're doing this, you may as well use LINQ: efList.Select(e => new P(e)).ToList().

like image 37
Tim Robinson Avatar answered Oct 13 '22 01:10

Tim Robinson