Есть ли способ избежать передачи двух общих параметров в моем методе расширения?

У меня есть класс типа Installer, где TModel имеет ограничение. Я хочу создать метод расширения с сигнатурой типа :\

public static void DoRepetitiveStuff<TOtherObject, TModel>(this Installer<TModel> installer)
where TModel : class, IConstraint, new()
where TOtherObject : class, IOtherConstraint, new()
{
   installer.DoSomeStuff<TOtherObject>(c => { });
}

цель состоит в том, чтобы в конечном итоге я мог вызвать функцию, используя простой installer.DoRepetitiveStuff<TOtherObject>();

По какой-то причине, когда я вызываю эту функцию для другого файла. Он жалуется, что нет никакого метода расширения, который принимает существующий установщик... Мне нужно использовать его с:

installer.DoRepetitiveStuff<TOtherObject, TModel>();

Кто-нибудь знает, почему?


person Jean-Baptiste Zeller    schedule 18.02.2020    source источник
comment
Вы можете ввести промежуточный класс с универсальным методом внутри, чтобы назвать его installer.GetExtension().DoRepetitiveStuff<TOtherObject>();, как здесь: stackoverflow.com/questions/16479623/   -  person Renat    schedule 18.02.2020
comment
Вы можете либо опустить все общие параметры, либо ни один из них. Он может определить только одно из двух, поэтому вариант none здесь невозможен, и вы должны явно указать оба.   -  person Joelius    schedule 18.02.2020


Ответы (1)


Компилятор C# не может определить частичную общую подпись. Это в основном все или ничего. Почему?

Допустим, ваш код принят, а затем вы создаете новый метод:

public static void DoRepetitiveStuff<TOtherObject>(this Installer installer)
where TOtherObject : class, IOtherConstraint, new()
{
   installer.DoOtherStuff();
   installer.DoSomeStuff<TOtherObject>(c => { });
}

Итак, какой метод вызывает ваш код? Ваш или этот? Мы не можем знать, потому что это неоднозначно.

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

В качестве альтернативы вам нужно будет ввести другой класс, который может сделать вывод за вас. Однако на данном этапе более лаконично просто указать оба универсальных типа.

person Clay07g    schedule 18.02.2020
comment
О, я понял. Если вы создадите вторую подпись с помощью ‹TOtherType› (Installer‹ConcreteType›), она будет конфликтовать с моей предыдущей декларацией, если она не включала «все или ничего для вывода типа». - person Jean-Baptiste Zeller; 22.02.2020