2011-03-09 29 views
3

簡化的下面的例子中,我想在分配之前定義result。下面的linq查詢返回匿名類型的列表。 result將作爲IEnumerable <'a>從linq查詢中提取出來,但我無法在方法的頂部定義它。我正在嘗試做什麼(在.NET 4中)?如何預先定義一個包含匿名類型的變量?

  bool large = true; 
      var result = new IEnumerable(); //This is wrong 

      List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>(); 

      if (large) 
      { 
       result = from n in numbers 
          where n > 5 
          select new 
          { 
           value = n 
          }; 
      } 
      else 
      { 
       result = from n in numbers 
          where n < 5 
          select new 
          { 
           value = n 
          }; 
      } 

      foreach (var num in result) 
      { 
       Console.WriteLine(num.value); 
      } 

編輯:爲了清楚我知道我不需要上面例子中的匿名類型。這只是用一個簡單的例子來說明我的問題。

回答

3

匿名類型只能var聲明。好的是,具有相同屬性的匿名類型將是相同的類型。如果你真的需要它(這個樣本中,你不需要它),那麼你可以這樣寫:

var result = Enumerable.Repeat(new {value = 0}, 0); // stub value which will give needed type 
if (...) 
{ 
    result = ...; 
} 
else 
{ 
    result = ...; 
} 

PS:這是可能的,即使在以前的.NET版本(低於4.0)

+1

請注意,這是「相同的屬性名稱,具有相同的屬性類型,具有相同的順序」。 – 2011-03-09 17:50:34

+0

是的,這是有效的,正是我所期待的。謝謝! – HitLikeAHammer 2011-03-09 17:57:23

1

您可以將其設置爲IEnumerable,只需在查詢中選擇'n',而不是創建匿名類型。 EG:

IEnumerable<int> result = null; 

result = from n in numbers 
     where n > 5 
     select n; 

如果你實際上在做需要匿名類型,然後 - 因爲你正在使用C#4 - 你可以聲明IEnumerable<dynamic> result,和你的代碼的其餘部分將正常工作。

+2

這不回答這個問題 - 這不是一個匿名類型 – BrokenGlass 2011-03-09 17:45:10

+0

我認爲示例代碼旨在說明目標。如果沒有想到,這絕對是最好的方式! – Reddog 2011-03-09 17:48:13

+0

他在示例中所做的操作不需要匿名類型,但如果他確實需要它,則應使用IEnumerable 。 – 2011-03-09 17:48:35

0

您必須事先定義類型。例如。

public class TheNumber 
{ 
    public int Number { get; set; } 
} 

....

IEnumerable<TheNumber> result; 
result = numbers.Where(n => n > 5).Select(n => new TheNumber() { Number = n }); 
1

我喜歡Snowbear的回答,如果你真的做到這一點...但我個人至少嘗試,以避免陷入這種情況。例如,即使保持的匿名類型,我想你原來的代碼更改爲:

bool large = true; 
var result = new IEnumerable(); //This is wrong 

List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>(); 

Func<int, bool> predicate = large ? new Func<int, bool>(x => x > 5) 
            : x => x < 5; 
var result = numbers.Where(predicate) 
        .Select(x => new { value = x }); 

foreach (var num in result) 
{ 
    Console.WriteLine(num.value); 
} 

注意這是如何去掉重複的 - 它更清晰的件事large影響是謂語。

我發現代碼最終變得更清晰,如果變量只分配一個值,理想情況下在聲明點。

顯然這並不總是可行的,但在可能的情況下值得記住。在哪裏不是可能,Snowbear的答案是好的,並保證工作。

0

如果在創建匿名類型後不需要任何條件部分,則可以在部分中構建LINQ查詢。否則,定義一個新的結構/類來代替匿名類型可能更爲明智。

bool large = true; 
List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>(); 

IEnumerable<int> query; 
if (large) { 
    query = query.Where(n => n > 5); 
} else { 
    query = query.Where(n => n < 5); 
} 

var result = query.Select(n => new { Value = n }); 

foreach (var num in result) { 
    Console.WriteLine(num.Value); 
} 
相關問題