Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# more specific version on generic function

Tags:

c#

generics

I have the following function

public static T Translate<T>(T entity)
{
    ....
}

Now if T is en IEnumerable<> I want to have a different behaviour so I made a second function

public static IEnumerable<T> Translate<T>(IEnumerable<T> entities)
{
    ....
}

When I invoke it like this

IEnumerable<string> test = new List<string>().AsEnumerable();
Translate(test);

However when I invoke it like this

Func<IEnumerable<string>> func = () => new List<string>().AsEnumerable();
Translate(func.Invoke())

It goes to the first one. Why does this happen and what is the best construction to solve this?

UPDATE

I build a new example with the problem

static void Main(string[] args)
{
    Func<IEnumerable<string>> stringFunction = () => new List<string>().AsEnumerable();
    InvokeFunction(ExtendFunction(stringFunction));
}

private static T Convert<T>(T text) where  T : class 
{
    return null;
}

private static IEnumerable<T> Convert<T>(IEnumerable<T> text)
{
    return null;
}

private static Func<T> ExtendFunction<T>(Func<T> func) where T : class 
{
    return () => Convert(func.Invoke());
}

private static T InvokeFunction<T>(Func<T> func)
{
    return func.Invoke();
}

The first function gets invoken now when I expect the second to be invoked.

like image 512
Dommicentl Avatar asked Aug 29 '14 07:08

Dommicentl


1 Answers

You need to either add a second overload of ExtendFunction:

private static Func<IEnumerable<T>> ExtendFunction<T> (Func<IEnumerable<T>> func) where T : class
{
    return () => Convert(func.Invoke());
}

Or make the first overload invoke Convert method dynamically:

private static Func<T> ExtendFunction<T> (Func<T> func) where T : class
{
    return () => Convert((dynamic)func.Invoke());
}

The reason is that your ExtendFunction method chooses Convert method at compile time. You can avoid that be either adding a second overload of ExtendFunction which chooses the Convert method you need, or by moving the choice of Convert method to run time.

like image 58
Athari Avatar answered Oct 05 '22 21:10

Athari