In VB, the following is a valid object initializer in which one member intializer references the value of another member that has previously been initialized.
new MyObject() with {.Property1="x", .Property2 = .Property1 + "y"}
If I try to do the same in C#
using
new MyObject() {Property1 = "x", Property2 = Property1 + "y"}
I get the error
The name 'Property1' does not exist in the current context.
It is a little surprising since there is a fair amount of parity between the two languages but perhaps this is one of those few differences.
Is there a way to do this in C#
? For those wondering what the specific use case may be, I am constructing a composite object structure using a fairly complex LINQ query.
IEnumerable<Question> query =
(from q in dtQuestions.AsEnumerable()
join a in dtAnswers.AsEnumerable() on q.Field<int>("question_type_id") equals a.Field<int>("question_type_id") into Group
select new Question()
{
Id = q.Field<int>("question_type_id"),
SequenceNumber = q.Field<int>("sequence_no"),
IsChild = q.Field<bool>("isChildQuestion"),
EktronContentKey = q.Field<string>("ektron_content_key"),
Text = q.Field<string>("description"),
QuestionKindId = q.Field<int>("question_kind_type_id"),
Answers = (from a2 in Group
select new Answer()
{
Id = a2.Field<int>("answer_type_id"),
SequenceNumber = a2.Field<int>("sequence_no"),
EktronContentKey = a2.Field<string>("ektron_content_key"),
Text = a2.Field<string>("description"),
IsSelected = a2.Field<bool>("isSelected"),
ImageKey = q.Field<int>("question_type_id") == 2 ? "" : (Id % 2 == 0 ? "heating-gas-modern.png" : "heating-gas-condensing.png"),
ChildQuestionIds =
(from r in dtAnswerChildQuestions.AsEnumerable()
where r.Field<int>("answer_type_id") == Id
select r.Field<int>("question_type_id")).ToArray()
}).ToArray(),
SelectedAnswerId = QuestionKindId == 1 ?
(from Answer a3 in Answers
where a3.IsSelected == true
select a3.Id).SingleOrDefault() :
0,
SelectedAnswerIds = QuestionKindId == 2 ?
(from Answer a4 in Answers
where a4.IsSelected == true
select a4.id).ToArray() :
new int() { }
}
);
The real problem to address in this is the reference to the Answers property in the LINQ expression used to assign values to SelectedAnswerId and SelectedAnswerIds. I may have to factor those two expressions out into their own standalone assignments.
I wound up having to resolve this by using a secondary for loop. The code was a bit too complicated to do with LET statements.
IEnumerable<Question> query =
(from q in dtQuestions.AsEnumerable()
join a in dtAnswers.AsEnumerable() on q.Field<int>("question_type_id") equals a.Field<int>("question_type_id") into Group
select new Question()
{
Id = q.Field<int>("question_type_id"),
SequenceNumber = q.Field<int>("sequence_no"),
IsChild = q.Field<bool>("isChildQuestion"),
EktronContentKey = q.Field<string>("ektron_content_key"),
Text = q.Field<string>("description"),
QuestionKindId = q.Field<int>("question_kind_type_id"),
Answers = new AnswerCollection((from a2 in Group
select new Answer()
{
Id = a2.Field<int>("answer_type_id"),
SequenceNumber = a2.Field<int>("sequence_no"),
EktronContentKey = a2.Field<string>("ektron_content_key"),
Text = a2.Field<string>("description"),
IsSelected = a2.Field<bool>("isSelected"),
ImageFileId = a2.Field<int?>("file_id"),
ChildQuestionIds =
new Collection<int>((from r in dtAnswerChildQuestions.AsEnumerable()
where r.Field<int>("answer_type_id") == a2.Field<int>("answer_type_id")
select r.Field<int>("question_type_id")).ToList())
}))
}
);
foreach (var question in query)
{
question.SelectedAnswerId = question.QuestionKindId == 1 ?
(from Answer a3 in question.Answers
where a3.IsSelected == true
select a3.Id).SingleOrDefault() :
0;
question.SelectedAnswerIds = question.QuestionKindId == 2 ?
new Collection<int>((from Answer a4 in question.Answers
where a4.IsSelected == true
select a4.Id).ToList()) :
new Collection<int>();
this.Add(question);
}