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?
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.
See more on this question at Stackoverflow