我有这些课程:
public class BaseGame<T> where T : BaseQuestion
{
//some fileds and methods
}
public class BaseQuestion
{
//some fileds and methods
}
public class Question : BaseQuestion
{
//some fileds and methods
}
public class SampleGame : BaseGame<Question>
{
//some fileds and methods
}
每当我想将BaseGame转换为SampleGame时,我都会收到错误。
void SetValue(BaseGame<BaseQuestion> _game)
{
SampleGame = (SampleGame) _game;
}
无法将BaseGame类型隐式转换为SampleGame。 如何解决这个问题?
感谢。
答案 0 :(得分:0)
将您的代码更改为:
public interface IBaseGame<out T> where T : BaseQuestion
{
}
public class BaseGame<T> : IBaseGame<T>
where T : BaseQuestion
{
}
public class BaseQuestion
{
}
public class Question : BaseQuestion
{
}
public class SampleGame : BaseGame<Question>
{
}
然后你的方法:
void SetValue(IBaseGame<BaseQuestion> _game)
{
var SampleGame = (SampleGame) _game;
}
为什么你的代码被破坏了?
你无法进行演员表,因为BaseGame
不是协变的。这意味着编译无法保证演员阵容是安全的。例如,以下示例:
public class BaseGame<T> where T : BaseQuestion
{
private List<T> Questions { get; set; }
public void AddQuestion(T question) { Questions.Add(question); }
}
var game = new BaseGame<Question> { Questions = new List<Question> };
game.AddQuestion(new Question());
好的,现在你的游戏有一个Question
列表,其中有一个问题。现在让我们投吧:
public class BrokenQuestion : BaseQuestion
{
}
public class BrokenGame : BaseGame<BrokenQuestion>
{
}
var brokenGame = (BrokenGame)game;
brokenGame.Add(new BrokenQuestion());`
糟糕!我们刚刚向BrokenQuestion
添加了List<Question>
。不好。
将模板参数定义为out T
而不是T
意味着我们正在签订一份我们不会接受 T
子类的合同,但我们可以返回他们。这意味着它现在非法公开AddQuestion(T question)
。现在,编译器可以确保永远不会向BrokenQuestion
添加List<Question>
。
有关详细信息,请see here