我有两个名为Post和Question的课程。问题定义为:
public class Question : Post
{
//...
}
我的问题类不会覆盖Post的任何成员,它只是表达了一些其他成员。
我有一个Post类型的对象,其成员已填充。现在,我想将其转换为一个问题,以便我可以为少数其他成员添加值。
这是我当前的代码,使用显式强制转换:
Post postToQuestion = new Post();
//Populate the Post...
Question ques = (Question)postToQuestion; //--> this is the error!
//Fill the other parts of the Question.
我收到了InvalidCastException。我做错了什么?
答案 0 :(得分:22)
问题是你无法从父母转变为孩子。您可以为子类创建一个构造函数,将父类作为参数: 问题问题=新问题(myPost);
您还可以使用隐式运算符来简化此操作: 问题问题= myPost;
http://www.codeproject.com/KB/cs/Csharp_implicit_operator.aspx
编辑: 实际上,我只是尝试为你做一个隐式运算符的演示:
class Question : Post
{
public Question()
{
//...
}
public Question(Post p)
{
// copy stuff to 'this'
}
public static implicit operator Question(Post p)
{
Question q = new Question(p);
return q;
}
}
但显然C#不允许你用基类进行隐式转换。
答案 1 :(得分:6)
此时发布不是问题,CLR正在抱怨。你可以将问题转发给Post,但不是反之亦然。现在,如果您对帖子的高级别引用是知道是一个问题,那么您可以像这样低估:
public Post Post
{
set
{
if (value is Question)
{
question = (Question)value;
}
}
}
但即使这是a code smell。
但我认为你想要实现的目标可以在没有类型转换的情况下实现,或者根本没有继承。遵循古老的"favor encapsulation over inheritance"原则,为什么不将Post对象包装到Question对象中,如下所示:
public class Question
{
Post post;
public Question(Post post)
{
this.post = post;
}
}
假设您已为Post的相关成员定义了属性,而不是
Question ques = (Question)post;
你有
Question ques = new Question(post);
答案 2 :(得分:4)
执行强制转换不会更改您正在投射的对象 - 因此无法将缺少的“问题”成员添加到“发布”对象中。我担心您只需要创建一个新的“问题”对象,并将您感兴趣的成员从“发布”复制到“问题”。
请注意,从“问题”到“发布”,以另一种方式进行投射可以正常工作,因为您可以将问题视为帖子而无需更改 - 所有必填字段都已存在。
答案 3 :(得分:3)
如果您想要更改类型,您需要编写代码,或者有时您可以序列化。转换不会更改类型(除非已编写自定义运算符)。
最简单的选项是首先将其创建为正确的类型:
Post post = new Question();
或者,添加转化运算符或其他方法,以便从帖子中创建Question
:
class Question {
public Question(Post post) {
this.Author = post.Author;
this.Body = post.Body;
// ...
}
}
...
Question question = new Question(post);
您还可以使用其他技巧,例如基于反射的属性副本或序列化;例如,使用MiscUtil:
Question question = PropertyCopy<Question>.CopyFrom(post);
或protobuf-net(需要一些额外的序列化属性):
Question question = Serializer.ChangeType<Post,Question>(post);
答案 4 :(得分:0)
你可以这样做:
public Question(Post P) : base(p) {...}
class Post
{
public Post(Post P)
{
populate(P.ID);
}
void populate(int ID)
{
// load from DB, or however it happens
}
}
...如果你从数据存储区实例化Post?