Я начал с вашего кода (более или менее), и резарпер сразу же сказал мне, что приведение к T не нужно:
public class Test
{
static TournamentGame<T, Y> make16Game<T, Y>(int gameId, int seed1, int seed2, List<Y> teams)
where T : TournamentTeam<Y>
where Y : Team
{
return new TournamentGame<T, Y>(gameId,
new TournamentTeam<Y>(seed1, teams[seed1 - 1]),
new TournamentTeam<Y>(seed2, teams[seed2 - 1]));
}
}
internal class Team { }
internal class TournamentTeam<T> {
public TournamentTeam(int seed1, Team team) {
throw new NotImplementedException();
}
}
internal class TournamentGame<T, Y> {
public TournamentGame(int gameId, TournamentTeam<Y> tournamentTeam, TournamentTeam<Y> tournamentTeam1) {
throw new NotImplementedException();
}
}
Таким образом, потребность в приведении к Т приходит откуда-то еще. Если вам нужен определенный тип «конструктора» для T, вы всегда можете передать фабричный метод:
static TournamentGame<T, Y> make16Game<T, Y>(int gameId, int seed1, int seed2, Func<int, Y, T> tournamentTeamFactory, List<Y> teams)
where T : TournamentTeam<Y>
where Y : Team
{
return new TournamentGame<T, Y>(gameId,
tournamentTeamFactory(seed1, teams[seed1 - 1]),
tournamentTeamFactory(seed2, teams[seed2 - 1]));
}
РЕДАКТИРОВАТЬ: Учитывая код конструктора, который вы используете, ясно, зачем вам приведение к T (и почему передача фабричного метода, как я предлагаю выше, хорошая идея). Если вы хотите ограничить TournamentGame только использованием TournamentTeams (что ваш код эффективно делает), тогда предоставьте конструктор, который напрямую принимает TournamentTeam. Если нет, то вам не следует создавать TournamentTeams в вашей функции make16Game. Представьте себе следующее:
public class AllStarTeam<T> : TournamentTeam<T> where T : Team
{
public AllStarTeam(int seed1, Team team) : base(seed1, team)
{
throw new NotImplementedException();
}
}
Затем это компилируется, но выдает исключение времени выполнения (Плохая вещь):
Test.make16Game<AllStarTeam<T>, T>(5, 5, 5, new List<T>());