C# can often infer a generic type argument from method arguments.

Type Inference

TypeInference.cs
using System;

class Program
{
    static string Pair<T>(T left, T right)
    {
        return left + "|" + right;
    }

    static void Main()
    {
        int right = ;
        string numbers = Pair(3, right);
        string words = Pair("red", "blue");

        Console.WriteLine($"right={right}");
        Console.WriteLine($"numbers={numbers}");
        Console.WriteLine($"words={words}");
    }
}
using System;

class Program
{
    static string Pair<T>(T left, T right)
    {
        return left + "|" + right;
    }

    static void Main()
    {
        int right = ;
        string numbers = Pair(3, right);
        string words = Pair("red", "blue");

        Console.WriteLine($"right={right}");
        Console.WriteLine($"numbers={numbers}");
        Console.WriteLine($"words={words}");
    }
}
using System;

class Program
{
    static string Pair<T>(T left, T right)
    {
        return left + "|" + right;
    }

    static void Main()
    {
        int right = ;
        string numbers = Pair(3, right);
        string words = Pair("red", "blue");

        Console.WriteLine($"right={right}");
        Console.WriteLine($"numbers={numbers}");
        Console.WriteLine($"words={words}");
    }
}
type inference Type inference lets the compiler fill in a generic type argument.