使用 C# 中的对象初始化语法将内部对象的成员设置为外部对象
Set inner object's member as outer object using the object initialization syntax in C#
上下文
- 我有一个
List<T>
类型 Question
。
- Class
Question
,依次包含一个List<Answer>
.
- Class
Answer
有一个名为 public Question Question { get; set; }
的成员,它存储了问题的答案。
我正在使用集合初始化语法将 Question
项添加到列表中,并使用对象初始化来创建新的 Question
。在这样做的同时,我还使用对象初始化语法(嵌套)创建了新的 Answer
对象。
问题
如何设置内部 Answer
class 的 Question
成员来引用封闭的 Question
对象?我知道创建 Answer
的时间点,Question
甚至还没有完全初始化。但是有没有办法获得外部 Question
实例,以便我可以将它设置为内部 Answer
.
代码
private List<Question> questions = new()
{
new Question
{
Id = 1,
Text = "Test Question 1",
Difficulty = QuestionDifficulty.Easy,
Answers =
{
new Answer { Id = 1, Question = [?] },
new Answer { Id = 2, Question = [?] } // What should replace [?] here?
}
}
};
这是不可能的。但是您可以在创建答案后将问题设置为所有答案。在使用集合初始化期间,不要为问题 属性 赋值。在您的构造函数中,您执行以下操作:
foreach(var question in questions)
{
foreach(var answer in question.Answers)
{
answer.Question = question;
}
}
你不能在 collection/object 初始化程序中这样做,但我认为你一开始就不应该在那里这样做。手写每个答案对应的问题是很容易出错的。有时您可能也会忘记这样做。
我建议您为 Question
中的 Answers
属性 添加一个自定义 setter,它也设置答案的 Question
属性 :
private List<Answer> answers;
public List<Answer> Answers {
get => answers;
set {
// If you feel like it, you can also set the old answers' questions to null
answers = value;
foreach (var answer in answers) {
answer.Question = this;
}
}
}
然后在对象初始化器中,初始化答案列表,而不是仅仅添加:
private List<Question> questions = new()
{
new Question
{
Id = 1,
Text = "Test Question 1",
Difficulty = QuestionDifficulty.Easy,
Answers = new List<Answer> // <--- here!
{
new Answer { Id = 1 },
new Answer { Id = 2 }
}
}
};
这编译成类似的东西:
var question = new Question();
...
var list = new List<Answer>();
var answer1 = new Answer();
answer1.Id = 1;
var answer2 = new Answer();
answer2.Id = 2;
list.Add(answer1);
list.Add(answer2);
question.Answers = list;
如您所见,setter 被调用,答案'Question
属性 将被设置。
上下文
- 我有一个
List<T>
类型Question
。 - Class
Question
,依次包含一个List<Answer>
. - Class
Answer
有一个名为public Question Question { get; set; }
的成员,它存储了问题的答案。
我正在使用集合初始化语法将 Question
项添加到列表中,并使用对象初始化来创建新的 Question
。在这样做的同时,我还使用对象初始化语法(嵌套)创建了新的 Answer
对象。
问题
如何设置内部 Answer
class 的 Question
成员来引用封闭的 Question
对象?我知道创建 Answer
的时间点,Question
甚至还没有完全初始化。但是有没有办法获得外部 Question
实例,以便我可以将它设置为内部 Answer
.
代码
private List<Question> questions = new()
{
new Question
{
Id = 1,
Text = "Test Question 1",
Difficulty = QuestionDifficulty.Easy,
Answers =
{
new Answer { Id = 1, Question = [?] },
new Answer { Id = 2, Question = [?] } // What should replace [?] here?
}
}
};
这是不可能的。但是您可以在创建答案后将问题设置为所有答案。在使用集合初始化期间,不要为问题 属性 赋值。在您的构造函数中,您执行以下操作:
foreach(var question in questions)
{
foreach(var answer in question.Answers)
{
answer.Question = question;
}
}
你不能在 collection/object 初始化程序中这样做,但我认为你一开始就不应该在那里这样做。手写每个答案对应的问题是很容易出错的。有时您可能也会忘记这样做。
我建议您为 Question
中的 Answers
属性 添加一个自定义 setter,它也设置答案的 Question
属性 :
private List<Answer> answers;
public List<Answer> Answers {
get => answers;
set {
// If you feel like it, you can also set the old answers' questions to null
answers = value;
foreach (var answer in answers) {
answer.Question = this;
}
}
}
然后在对象初始化器中,初始化答案列表,而不是仅仅添加:
private List<Question> questions = new()
{
new Question
{
Id = 1,
Text = "Test Question 1",
Difficulty = QuestionDifficulty.Easy,
Answers = new List<Answer> // <--- here!
{
new Answer { Id = 1 },
new Answer { Id = 2 }
}
}
};
这编译成类似的东西:
var question = new Question();
...
var list = new List<Answer>();
var answer1 = new Answer();
answer1.Id = 1;
var answer2 = new Answer();
answer2.Id = 2;
list.Add(answer1);
list.Add(answer2);
question.Answers = list;
如您所见,setter 被调用,答案'Question
属性 将被设置。