我在一个奇怪的环境中玩弄仿制药,我遇到了一个奇怪的情况,其“解决方案”我不希望工作。这是有问题的代码......
static TournamentGame<T, Y> make16Game<T, Y>(int gameId, int seed1, int seed2, List<Y> teams)
where T : TournamentTeam<Y>
where Y : Team
{
/*
* bunch of code removed for clarity
*/
// return that bad boy
return new TournamentGame<T, Y>(gameId,
(T)(new TournamentTeam<Y>(seed1, teams[seed1 - 1])),
(T)(new TournamentTeam<Y>(seed2, teams[seed2 - 1])));
}
看看这个,我看不到编译器是如何允许的。我的直觉是,如果我使用除T
之外的TournamentTeam
调用此错误,我将收到运行时错误。如果我没有放入演员表,我会收到编译错误。我的直觉是否正确?我要做的是强制执行约束T
必须有一个带String
和Y
参数的构造函数,但这是另一个问题。我想我也可以使用反射来获取T
的构造函数,但那里的乐趣在哪里?
无论如何,想法?
EDIT
TournamentGame
如下所示:
public class TournamentGame<T, Y> : Game<T>
where T : TournamentTeam<Y>
where Y : Team
{
public TournamentGame(int id, T t1, T t2, Region<T, Y> region = null)
: base(id, t1, t2)
{
// do your thang
}
}
public class Game<T>
where T : Team
{
private T mTeam1 = null;
private Game(int id)
{
// do your thang
}
public Game(int id, T t1, T t2)
: this(id)
{
// do your thang
}
public T Team1
{
get
{
// do your thang
}
}
}
很抱歉将其遗漏。
答案 0 :(得分:1)
如果我理解正确,则无法在泛型中对构造函数指定此类约束。 Here is some thoughts与您的问题有关。
答案 1 :(得分:1)
我开始使用你的代码(或多或少)和resharper立即告诉我,对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的演员阵容来自其他地方。如果你想要一个特定类型的“构造函数”用于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的构造函数。如果没有,那么你不应该在make16Game函数中创建TournamentTeams。想象一下:
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>());