我想为泛型类A创建一个扩展方法,它采用另一个泛型类型(在本例中为TC),但我想这可能吗?
class Program
{
static void Main(string[] args)
{
var a = new A<B, B>();
a.DoIt<B>();
}
}
static class Ext
{
public static A<TA, TB> DoIt<TA, TB, TC>(this A<TA, TB> a)
{
return a;
}
}
class A<TA, TB> { }
class B { }
答案 0 :(得分:4)
如果您可以接受轻微的语法更改,那么就可以。
将其更改为:
var a = new A<B, B>();
a.Do().It<B>();
诀窍是Do方法是A<TA, TB>
上的扩展方法:
public static Doer<TA, TB> Do<TA, TB>(this A<TA, TB> a)
{
return new Doer<TA, TB>(a);
}
诀窍在于,此签名允许类型推断从a
获取TA和TB,这样您就不必明确指定它们。
Doer类提供了您需要的通用方法:
public class Doer<TA, TB>
{
public void It<TC>() { }
}
答案 1 :(得分:3)
不,这是可能的,但你必须给编译器一些可接受的“TC”的上下文。第三个参数TC不会在代码中的任何其他位置使用,因此它可能是任何东西,因此,编译器会抱怨。但是,如果将传入参数添加到TC类型的扩展方法中,则可以实现编译器可以推断TC的实际类型的情况,然后您甚至不必指示调用时的类型方法:
class Program
{
static void Main(string[] args)
{
var a = new A<B, B>();
string tc = "Hi!";
a.DoIt(tc);
}
}
static class Ext
{
public static A<TA, TB> DoIt<TA, TB, TC>(this A<TA, TB> a, TC c)
{
return a;
}
}
class A<TA, TB> { }
class B { }
但是你必须给编译器一些上下文。
话虽如此,指定通用参数是一种全有或全无的努力。编译器可以推断出每个泛型类型参数的类型,或者它不能,并且你必须告诉它所有类型参数是什么。
答案 2 :(得分:1)
你是对的,这是不可能的。您必须指定所有类型参数(TA
,TB
和TC
),或者不指定任何类型参数(并将其留给编译器的类型推断)。
有几种可能性:
DoIt
转换为实例方法(虽然我猜您已故意将其作为扩展方法)DoIt
添加另一个参数,以某种方式约束TC
,这意味着类型推断将起作用有关第二个示例,请查看Enumerable.Select
:它有两个类型参数,对于源类型和目标类型,但它们都是从传递给Select
的参数推断出来的。 / p>