我有一些代码可以根据用户输入生成答案。但是在某些情况下,我需要稍后通过调用SetAnswers
来更新值。但是,当我编译代码时,会出现以下错误:
NullReferenceException:对象引用未设置为对象的实例
在箭头标记的行上出现此错误。
参见下面的代码:
public class Generate_Questions : MonoBehaviour{
public Question q5, q4;
void Start(){
q4 = create_question("Select object to edit", EXTERNAL);
Visual_Question vq1 = new Visual_Question(1, q4, new vector(1,1,1), Ui, Canvas);
vq1.draw_question();
}
void Update(){
}
public class Visual_Question : Generate_Questions{
public Visual_Question(int order_id, Question q, Vector2 loc, Dictionary<string, RectTransform> ui, RectTransform canvas){
}
public void draw_question(){
q4.SetAnswers(new Answer[]{ <--------- this generates the error.
new Answer(null, "Select an option")
});
}
}
public class Question{
public string text;
public int answers_loc;
public List<Answer> answers;
public Question(string q_text, int answers_loc){
answers = new List<Answer>();
this.text = q_text;
this.answers_loc = answers_loc;
}
public void SetAnswers(Answer[] c_answers){
foreach(Answer answer in c_answers){
this.answers.Add(answer);
}
}
public bool CheckIfAnswersAvailable(){
if(answers.Count > 0){
return true;
}else{
return false;
}
}
public int QuestionLocation(){
return answers_loc;
}
}
public Question create_question(string text, int a_type){
Question Q = new Question(text, a_type);
return Q;
}
public interface IAnswer{
string GetText();
string GetDataType();
object GetValue();
Question GetNextQuestion();
}
public class Answer : IAnswer{
public string text;
public Question next = null;
public int? action = null;
public Element obj = null;
public string property = null;
public float? value = null;
public Answer(Question next, string text){
this.text = text;
this.next = next;
}
public Answer(Question next, string text, Element obj, int? action){
this.action = action;
this.text = text;
this.next = next;
this.obj = obj;
}
public Answer(Question next, string text, Element obj, int? action, string property, float? value){
this.action = action;
this.next = next;
this.text = text;
this.obj = obj;
this.property = property;
this.value = value;
}
public string GetText(){
return text;
}
public string GetDataType(){
throw new System.NotImplementedException();
}
public object GetValue(){
return value;
}
public Question GetNextQuestion(){
return next;
}
}
}
我将如何解决此问题?我是C#的新手。所以我的问题可能已经回答了,但我只是不知道我在寻找什么。
答案 0 :(得分:1)
我假设IAnswer[]
是一个接口,并且由于您尝试初始化抽象对象,因此会遇到运行时异常
NullReferenceException:对象引用未设置为对象的实例
如果要创建IAnswer
对象的实例,则必须像类或结构一样重新构造它。
答案 1 :(得分:0)
您的Visual_Question类是从Generate_Questions派生的,因此您使用en draw_question的成员 q4 未初始化。这不是Generated_Questions的成员,而是未初始化的Visual_Question的成员。
答案 2 :(得分:0)
在Generate_Questions
中,您正在创建Visual_Question
的新实例,然后立即在该新实例上调用draw_question
。现在,您有一个问题的2个实例(均来自Generate_Questions
),但是只有其中一个具有Start
方法,该方法初始化了q4
。但是,如果您尝试从第二个实例调用Start
,则会发现自己陷入了一系列无限的递归调用中,并迅速因其他错误而崩溃(在这种情况下为堆栈溢出)。>
当前代码的一个问题是Generate_Questions
听起来比类更像是一个动作。我建议从Visual_Question
删除继承,并使其成为您将在Question
上实现的接口。 Question
应该应该删除create_question
方法。这可能属于MonoBehavior
脚本(从技术上讲,这是一种工厂方法-查找工厂模式-由于这是一个初学者,因此在此不做介绍)。
类似的东西(显然不完整):
public class Generate_Questions : MonoBehaviour
{
private IVisualQuestion q4;
void Start()
{
q4 = new Question("Select object to edit", EXTERNAL);
q4.DrawQuestion(new vector(1,1,1), Ui, Canvas)
}
void Update() {}
}
public interface IVisualQuestion
{
void DrawQuestion(Vector2 loc, Dictionary<string, RectTransform> ui, RectTransform canvas);
}
public class Question : IVisualQuestion
{
// ... insert the Question constructor and code here ...
// Implement VisualQuestion interface
public void DrawQuestion(Vector2 loc, Dictionary<string, RectTransform> ui, RectTransform canvas)
{
this.SetAnswers(new Answer[]{new Answer(null, "Select an option")});
}
}
通常,您可能不需要继承。当您学习更多C#时,您会发现继承将对您有所帮助。通常,使用界面是一种更好,更灵活的方法。正如评论者指出的那样,您可能不想继承MonoBehavior
。您真的只需要Unity引擎将直接处理的类。
另一注:C#中的约定是在PascalCase中命名方法,变量等,而不使用下划线分隔单词。