Дополнительный универсальный параметр в универсальных дополнительных методах?

Я хотел бы, делают дополнительный метод для универсального класса 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 { }
7
задан casperOne 26 February 2010 в 22:06
поделиться

3 ответа

Если вы согласитесь с небольшим изменением синтаксиса, это будет возможно.

Измените его на:

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>() { }
}
4
ответ дан 7 December 2019 в 05:21
поделиться

Нет, это возможно, но вы должны предоставить компилятору приемлемый контекст того, что такое «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 { }

Но вы должны дать компилятору некоторый контекст.

При этом определение общих параметров - это попытка сделать все или ничего. Либо компилятор может вывести типы каждого параметра универсального типа, либо он не может, и вы должны сообщить ему, что все они из себя представляют.

3
ответ дан 7 December 2019 в 05:21
поделиться

Вы правы, это невозможно. Вы должны либо указать все параметры типа ( TA , TB и TC ), либо ни один из них (и оставить это на усмотрение компилятора).

Пара возможностей:

  • Превратить DoIt в метод экземпляра (хотя я предполагаю, что вы специально сделали его методом расширения)
  • Добавьте еще один параметр в DoIt , который каким-то образом ограничивает TC , то есть вывод типа будет работать

Для примера второго, посмотрите на Enumerable.Select : он имеет два параметра типа для источника и типы назначения, но оба они выводятся из аргументов, переданных в Select .

1
ответ дан 7 December 2019 в 05:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: