0

I'm converting collection of types to collection of wrapper types

var buying = ord.Buying == null ? null : ord.Buying.Any() ? ord.Buying.Select<PurchasedBox, XXX.PurchasedBox>(x => x).ToList()
            : new List<XXX.PurchasedBox>();
var trading = ord.Trading == null ? null : ord.Trading.Any() ? ord.Trading.Select<TradedBox, XXX.TradedBox>(x => x).ToList()
            : new List<XXX.TradedBox>();

and also dictionary

(Any and null check) foo.ToDictionary(x => x.Key, x => (XXX.Summary)x.Value)

The types are converted using implicit conversion

implicit operator XXX.TradedBox(TradedBox box)

This pattern is repeated serval times, but I'm not sure if it's possible to write generic helper with implicit conversions e.g.

    public static List<TE> ConvertList<T, TE>(List<T> list)
    {
        if (list == null)
            return null;
        // compilation error cannot convert expression
        return list.Any() ? list.Select<T, TE>(x => x).ToList() : new List<TE>();
    }
Lukasz Madon
  • 14,664
  • 14
  • 64
  • 108
  • 4
    you can pass convertor in helper like `public static List ConvertList(List list, Func convert)` and pass it to select, also as variant `list.Select(x => (TE)x)` or `list.Cast()` – Grundy May 05 '15 at 15:55
  • (to original method in the post) I'm pretty sure you can't write just generic method as there is no way to have generic restriction for "T where has implicit cast operator"... Maybe questions about dealing with lack of generic restrictions for `operator +` may help - http://stackoverflow.com/questions/32664/is-there-a-constraint-that-restricts-my-generic-method-to-numeric-types (or @Grundy's creator function) – Alexei Levenkov May 05 '15 at 15:56
  • @Grundy Not sure how list.Cast() could work. – Lukasz Madon May 05 '15 at 16:37
  • @lukas try about [_Cast_](https://msdn.microsoft.com/en-us//library/bb341406(v=vs.110).aspx) in msdn – Grundy May 05 '15 at 17:53

1 Answers1

1

Try it, cast to dynamic type does the magic, but it's unsafe if you pass the wrong type (there is no constraint).

public static List<TE> ConvertList<T, TE>(List<T> list)
{
    if (list == null)
        return null;

    return list.Any() ? list.Select<T, TE>(x => (TE)(dynamic)x).ToList() : new List<TE>();
}

NOTE:
I've made the performance test, and it's right that using dynamic cost 3 times longer than using Func, or normal way (for this test).

public static List<TE> ConvertList<T, TE>(List<T> list)
    {
        return list.Any() ? list.Select<T, TE>(x => (TE)(dynamic)x).ToList() : new List<TE>();

    }
    public static List<Link> ConvertList1(List<LinkEntity> list)
    {
        return list.Any() ? list.Select<LinkEntity,Link>(x => x).ToList() : new List<Link>();

    }

    public static List<TE> ConvertList3<T, TE>(List<T> list,Func<T,TE> fuc)
    {
        return list.Any() ? list.Select<T, TE>(x => fuc(x)).ToList() : new List<TE>();

    }

The main:

var s1 = Stopwatch.StartNew();
        var a1 = Enumerable.Repeat(new LinkEntity { A = 10 }, 10000).ToList();
        for (int i = 0; i < 10000; i++)
        {
            var b1 = ConvertList<LinkEntity, Link>(a1);
        }

        Console.WriteLine(s1.ElapsedMilliseconds);

        var s2 = Stopwatch.StartNew();
        var a2 = Enumerable.Repeat(new LinkEntity { A = 10 }, 10000).ToList();
        for (int i = 0; i < 10000; i++)
        {
            var b2 = ConvertList1(a2);
        }

        Console.WriteLine(s2.ElapsedMilliseconds);

        var s3 = Stopwatch.StartNew();
        var a3 = Enumerable.Repeat(new LinkEntity { A = 10 }, 10000).ToList();
        for (int i = 0; i < 10000; i++)
        {
            var b3 = ConvertList3(a3, f => f);
        }

        Console.WriteLine(s3.ElapsedMilliseconds);

Result:
11609
4168
4611

nhabuiduc
  • 998
  • 7
  • 8