tags:

views:

70

answers:

4

I tried to apply operators on Generics (for my example ,multiplication)

    public static List<TOutput> Conversion<TOutput>(List<TInput> input)
    {
        List<TOutput> outList = new List<TOutput>();
        foreach(TInput tinput in input)
        {
            double dbl = tinput *tinput;
            outList.Add(dbl);

        }
        return outList;

    }

Any workaround for fixing it?

+5  A: 

Not possible without reflecting upon the type. There is some code that does this available as part of MiscUtil.

Porges
+1 for showing the utility
D'oh - I was too late ;-p
Marc Gravell
+1  A: 

The compiler shouldn't allow you to assign a double to an unknown type:

outList.Add(dbl);

For all it knows, you could be trying to assign a dbl to a type of FluxCapacitor. Your code is trying to accomplish two incompatible things: to return a list of generic (unknown) type, and 2) to force that type to be a double. This doesn't make sense, which is why you're having difficulty. You can use reflection (as Porges pointed out with an excellent link) to solve this dynamically, but you really need to ask yourself: why are you trying to assign a floating point number to a class that has an unknown type? The calling code could be asking for a result of List<bool>. How much sense would it make to try to assign

double foo = 1.5;
bool bar = foo;

? Zero. You can make the compiler do anything with enough somersaults, but you need to reevaluate the purpose of your routine, why you're trying to put a specific datatype into a generic one, and whether or not this routine needs to return a generic list.

David Lively
+1  A: 

The "MiscUtil" answer (already accepted) would be my first choice ;-p

You might also consider LINQ at the caller:

var prodList = originalList.Select(x=>x*x).ToList();

Since the caller knows the type (assuming it isn't itself generic, this should work.

Just for completeness, another option here (in 4.0) is dynamic:

public static List<TOutput> Conversion<TOutput>(List<TInput> input)
{
    List<TOutput> outList = new List<TOutput>();
    foreach(TInput tinput in input)
    {
        TOutput square = (dynamic)tinput * (dynamic)tinput;
        outList.Add(square);

    }
    return outList;
}
Marc Gravell
+1  A: 

You could use a cached lambda to do your calculation (and/or conversion).

This doesn't require the DLR or the dynamic keyword, so it's perfectly usable in C# 3.0

static class Squarer<T>
{
    private static readonly Func<T, T> _square;
    static Squarer()
    {
        ParameterExpression x = Expression.Parameter(typeof(T), "x");
        _square = Expression.Lambda<Func<T, T>>(
            Expression.Multiply(x, x),
            x).Compile();
    }

    public static T Square(T value)
    {
        return _square.Invoke(value);
    }
}

Console.WriteLine(Squarer<double>.Square(1234.5678));
Console.WriteLine(Squarer<decimal>.Square(1234.5678m));
Console.WriteLine(Squarer<int>.Square(1234));
ckknight