3

VB では、以下は有効なオブジェクト初期化子で、1 つのメンバー初期化子が以前に初期化された別のメンバーの値を参照します。

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

C#を使用して同じことをしようとすると

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

エラーが発生します

名前 'Property1' は現在のコンテキストに存在しません。

2 つの言語の間にかなりの量の同等性があるため、これは少し驚くべきことですが、おそらくこれは数少ない違いの 1 つです。

でこれを行う方法はあり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 プロパティへの参照です。これらの 2 つの式を独自のスタンドアロンの割り当てに分解する必要がある場合があります。

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"}

ただし、それはあなたの場合は醜いコードになります。これらの 2 つの式を独自のスタンドアロンの割り当てに分解する方がよい場合があります。

別の方法として、コードの一部を 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 に答える