Type arguments can't be inferred: why?

Viewed 53

The following c# code can't be inferred.

using System.Collections.Generic;

namespace Test
{
    public class Program
    {
        public static void Main()
        {
            Pipeline<string[]> s = null;

            // Compiles fine.
            s.WithNewDelimiters<Pipeline<string[]>, string[], string>();

            // Fails to compile.
            s.WithNewDelimiters();
        }
    }

    public class Pipeline<T> { }

    public static class Extensions
    {
        public static void WithNewDelimiters<TPipeline, TEnumerable, TElement>
            (this TPipeline pipeline)
            where TPipeline : Pipeline<TEnumerable>
            where TEnumerable : IEnumerable<TElement>
        {
        }
    }
}

Although the reason why this is a generic extension method isn't important, it's so that I can chain With-ers like this on any instance of Pipeline<T>

Now that's out of the way, here's my logic: I'm reading from left-to-right, so potentially this is not the algorithmic way that the C# compiler works.

  • First, look at TPipeline. TPipeline is a Pipeline<TEnumerable> We've passed in a Pipeline<string[]>. This means that TEnumerable == string[]
  • Next, look at TEnumerable. TEnumerable is a IEnumerable<string>
  • Since TElement is unconstrained, it can be anything, so it can be set to string.

Obviously this logic is either flawed or not how the C# compiler works. I think I've gone wrong by assuming that the value of one constraint affects another.

But I'm still not sure why this is ambiguous to the C# compiler. There is no other configuration of type parameters that could satisfy the requirements here, surely?

0 Answers
Related