Я хотел бы, делают дополнительный метод для универсального класса A, который берет еще один generictype (в этом примере 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 { }
Если вы согласитесь с небольшим изменением синтаксиса, это будет возможно.
Измените его на:
var a = new A<B, B>();
a.Do().It<B>();
Хитрость в том, что метод Do является методом расширения на A
:
public static Doer<TA, TB> Do<TA, TB>(this A<TA, TB> a)
{
return new Doer<TA, TB>(a);
}
Хитрость в том, что эта сигнатура позволяет определять тип TA и TB из a
, так что вам не нужно указывать их явно.
Класс Doer предоставляет общий метод, который вам нужен:
public class Doer<TA, TB>
{
public void It<TC>() { }
}
Нет, это возможно, но вы должны предоставить компилятору приемлемый контекст того, что такое «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 { }
Но вы должны дать компилятору некоторый контекст.
При этом определение общих параметров - это попытка сделать все или ничего. Либо компилятор может вывести типы каждого параметра универсального типа, либо он не может, и вы должны сообщить ему, что все они из себя представляют.
Вы правы, это невозможно. Вы должны либо указать все параметры типа ( TA
, TB
и TC
), либо ни один из них (и оставить это на усмотрение компилятора).
Пара возможностей:
DoIt
в метод экземпляра (хотя я предполагаю, что вы специально сделали его методом расширения) DoIt
, который каким-то образом ограничивает TC
, то есть вывод типа будет работать Для примера второго, посмотрите на Enumerable.Select
: он имеет два параметра типа для источника и типы назначения, но оба они выводятся из аргументов, переданных в Select
.