2012-06-07 17 views
2

在VB中,以下是一個有效的對象初始值設定項,其中一個成員初始化程序引用先前已初始化的另一個成員的值。如何引用C#成員初始值設定項中的另一個屬性值?

新的MyObject()含{.Property1 = 「X」,.Property2 = .Property1 + 「Y」}

如果嘗試使用做同樣在C#

新的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表達的答案屬性。我可能不得不將這兩個表達式分解爲他們自己的獨立作業。

回答

0

我最終不得不通過使用二級循環來解決這個問題。這段代碼對於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); 
    } 
0

我不知道在初始化前往Property1在C#中的訪問,但因爲你已經得到了價值Property1可用的,你可以做到以下幾點,希望編譯器能夠正確優化它:

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

儘管如此,這可能會導致醜陋的代碼,而將這兩個表達式分解爲他們自己的獨立作業可能會更好。

或者,您可以將一些代碼移動到Answers屬性設置器中,以便如果QuestionKindId已設置,則可以在內部設置屬性SelectedAnswerId和SelectedAnswerIds。

+0

我忽略了想Linq'Let'子句,所以OmegaMan有一個更乾淨的解決方案。 – MCattle

4

在C#中引用屬性是不可能的。由於您有「X」,因此很明顯,代碼可以寫成使用X.

由於這是Linq,您可能需要使用Let clause並創建業務邏輯處理來處理X甚至Y然後執行成員初始化。

相關問題