3

在 VB 中,以下是一个有效的对象初始化程序,其中一个成员初始化程序引用了之前已初始化的另一个成员的值。

new MyObject() with {.Property1="x", .Property2 = .Property1 + "y"}

如果我尝试在C#使用时做同样的事情

new MyObject() {Property1 = "x", Property2 = Property1 + "y"}

我得到错误

当前上下文中不存在名称“Property1”。

这有点令人惊讶,因为这两种语言之间存在相当多的平等,但也许这是少数几个差异之一。

有没有办法做到这一点C#?对于那些想知道具体用例可能是什么的人,我正在使用一个相当复杂的 LINQ 查询构造一个复合对象结构。

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() { }
 }
);

在此要解决的真正问题是对用于将值分配给 SelectedAnswerId 和 SelectedAnswerIds 的 LINQ 表达式中的 Answers 属性的引用。我可能不得不将这两个表达式分解为它们自己的独立分配。

4

3 回答 3

4

在 C# 中引用这样的属性是不可能的。由于您有“X”,因此很明显可以编写代码以使用 X。

由于这是 Linq,您可能希望使用Let 子句并创建业务逻辑处理来处理 X 甚至 Y,然后进行成员初始化。

于 2012-06-07T16:15:17.383 回答
1

我不确定是否可以在初始化程序中访问 C# 中的 Property1,但是由于您已经获得了 Property1 的值,您可以执行以下操作,并希望编译器对其进行正确优化:

new MyObject() {Property1 = "x", Property2 = "x" + "y"}

但是,这会使您的代码变得丑陋,并且您最好将这两个表达式分解为它们自己的独立分配。

或者,您可以将一些代码移动到 Answers 属性设置器中,以便如果 QuestionKindId 已设置,那么您可以在内部设置属性 SelectedAnswerId 和 SelectedAnswerIds。

于 2012-06-07T16:14:13.677 回答
0

我最终不得不通过使用辅助 for 循环来解决这个问题。代码有点太复杂,无法使用 LET 语句。

    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);
    }
于 2012-10-22T17:07:07.473 回答