How to work around rank N polymorphism in C#?

Suppose there is an identity function, which is:

T Id<T>(T t) { return t; }

What should I type F?

void F<T>(Func<T, T> f) { // This is not sound!
    System.Console.WriteLine("{0}", f(1));
    System.Console.WriteLine("{0}", f("one"));
}

static void Main() {
    F(Id);
}

I think C# doesn't have rank N polymorphism and C# cannot type F soundly. Is this right?

And then how to work around such issues?

Jon Skeet
people
quotationmark

It's not clear to me what you're trying to achieve, but you could do this with a non-generic interface that contains a generic method:

using System;

interface IGenericSameTypeFunction
{
    T Apply<T>(T input);
}

public class SimpleIdentityFunction : IGenericSameTypeFunction
{
    public T Apply<T>(T input) => input;
}

class Test
{    
    static void F(IGenericSameTypeFunction function)
    {
        Console.WriteLine(function.Apply(1));
        Console.WriteLine(function.Apply("one"));
    }

    static void Main()
    {
        F(new SimpleIdentityFunction());
    }
}

The important aspect is that by making the Apply method generic rather than the F method, you're saying "This is a function that can be applied in a type-safe way to any type."

There's no way of expressing that interface as a delegate type though.

people

See more on this question at Stackoverflow