具有泛型参数的扩展方法到泛型类

Kta*_*Kta 4 c# generics extension-methods

下面的代码无法编译:

 public static class MyExtensions
    {
        public static Bar<M> Convert<T,M>(this Foo<T> list)
        {
            return new Bar<M>();
        }
    }


    public class Program
    {
        static void Main(string[] args)
        {
            Foo<int> foo = new Foo<int>();

            foo.Convert<double>();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我必须明确指定 Foo 的泛型类型:

foo.Convert<int, double>();
Run Code Online (Sandbox Code Playgroud)

如果扩展方法具有单个泛型参数,则无需在方法调用期间指定类型。

为什么?我可以创建这样一个不需要我指定 Foo 参数的扩展方法吗?

Jon*_*eet 6

为什么?

类型参数推断要么全有要么全无:您必须在每个方法调用上指定所有类型参数,或者不指定任何类型参数。

M无法推断类型参数,因为它不会出现在参数列表中的任何位置。

几个选项:

  • 将两个方法链接在一起,以便第一个方法可以使用类型推断,第二个方法将允许您指定 的类型参数M

    Bar<double> bar = foo.CreateConverter()   // Implicitly CreateConverter<int>
                         .ConvertTo<double>() // Specify that you want a Bar<double>
    
    Run Code Online (Sandbox Code Playgroud)

    这将需要一个新的介入类型,例如Converter<T>CreateConverter. 那将有一个常规的实例方法ConvertTo<M>

  • M向方法添加类型参数Convert

    public static Bar<M> Convert<T, M>(this Foo<T> list, M ignored)
    
    Run Code Online (Sandbox Code Playgroud)

    ...然后您可以将该方法调用为:

    Bar<double> bar = foo.Convert(default(double));
    
    Run Code Online (Sandbox Code Playgroud)

    不可否认,这有点臭。

  • 不要使用扩展方法,而是使用泛型类型中的常规静态泛型方法 - 其中类型和方法都具有单个类型参数:

    public static class Converters<M>
    {
        public static Bar<M> Create<T>(Foo<T> foo) { ... }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    然后将其调用为:

    Bar<double> bar = Converters<double>.Create(foo);
    
    Run Code Online (Sandbox Code Playgroud)

    方法的类型参数可以从 推断出来foo,并且您显式指定该类型的类型参数。