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 参数的扩展方法吗?
为什么?
类型参数推断要么全有要么全无:您必须在每个方法调用上指定所有类型参数,或者不指定任何类型参数。
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,并且您显式指定该类型的类型参数。