2012-01-19 43 views
1

我有這樣的代碼在這種情況下,我可以使用匿名類型嗎?

// was before var groupTransactions; 
    IEnumerable<IGrouping<TransactionsGroupedByMonthYear, TransactionDto>> groupTransactions = null; 

DollarCapPeriod dollarCapPeriod = (DollarCapPeriod)Enum.Parse(typeof(DollarCapPeriod), reward.DollarCapPeriod); 
switch (dollarCapPeriod) 
{ 
    case DollarCapPeriod.Monthly: 
     groupTransactions = filterdTransactions.GroupBy(x => new { x.TransactionDate.Month, x.TransactionDate.Year }); 
     break; 
    case DollarCapPeriod.Yearly: 
    groupTransactions = filterdTransactions.GroupBy(x => new TransactionsGroupedByMonthYear { Month = 0, Year = x.TransactionDate.Year }); 
     break; 
    default: 
     break; 
} 

我想要做這樣的事情,但它要初始化的類型。所以我想知道有沒有在這附近或我必須做某種具體類型?如果是這樣,我怎麼跟groupBy一起做呢?

樣本數據

1/14/2012,5,Gas 
1/15/2012,5,Gas 
1/16/2012,5,Gas 
1/17/2012,5,Gas 

編輯

目前我想現在要做的用一個具體的支持,但我需要通過兩種不同的方式進行篩選。有時我只需要「年」,有時我需要「月」和「年」

我不知道該怎麼做。他們都需要進入相同的變量,所以他們需要是相同的類型。

回答

3

首先,不要混淆匿名類型的推斷類型。關鍵字var並不一定意味着某個類型是匿名的。就開發人員而言,匿名類型沒有名稱(編譯器當然會給出它,但這是一個您可以並應該忽略的實現細節)。推斷類型,使用var關鍵字,可能有一個名稱,您只需不必鍵入它。

這是絕不允許的說:

var x; 

因爲沒有從中推斷類型的信息。

在一般情況下,你可以在劃定範圍樣環的情況下使用匿名類型,try/catch語句等通過提前初始化的時間匿名類型的新實例:

var x = new { Month = 0, Year = 0 }; 
switch (foo) 
{ 
    case 1: 
    x = new { transaction.Month, transaction.Year }; 
} 

只要字段名稱和類型在兩個匿名類型初始值設定項之間相匹配,「實際」類型是相同的。

但是,在您的具體情況下,您不希望只使用匿名類型,因爲GroupBy不會返回匿名類型。它返回一個IEnumerable<IGrouping<TKey, TSource>>,在你的情況下,只有TKey是匿名的。雖然它是可能的要在代碼中聲明該類型,但它非常困難,並且會涉及臨時變量聲明僅僅是爲了匿名獲取他們的匿名信息typeof()。這幾乎肯定會是一個難以維繫的混亂。

相反,您應該聲明一個類型以便在您的組密鑰中使用。由於嵌套泛型,它仍然會很醜陋,但遠不及嘗試使用匿名類型那麼糟糕。

public class TransactionGroup 
{ 
    public int Month; 
    public int Year; 
} 

,讓您的分組:

IEnumerable<IGrouping<TransactionGroup, Transaction>> groupTransaction; 
var period = (Period)Enum.Parse(typeof(Period), record.Period); 
switch (period) 
{ 
    case Period.Monthly: 
     groupTransaction = transactions.GroupBy(x => new TransactionGroup 
      { 
      Month = x.TransactionDate.Month, 
      Year = x.TransactionDate.Year 
      }); 
     break; 
    case Period.Yearly: 
     groupTransaction = transactions.GroupBy(x => new TransactionGroup 
      {     
      Month = 0, 
      Year = x.TransactionDate.Year 
      }); 
     break; 
    default: 
     break; 
} 
+0

好吧那麼每年一次的開關如何。我只想按年分組,但仍然使用groupTransaction存儲它。在某些情況下,我需要按月份和年份進行分組,有時僅按年份分組。我想構建存儲LINQ的東西(認爲它會Func <>),然後在切換後將它傳遞給組,但我不知道如何做到這一點。 – chobo2

+0

最簡單的選擇是按月份= 0對所有內容進行分組,因爲您對實際月份不感興趣。有些人可能會爭辯說,「幻數」方法是錯誤的,但替代方案遠不能維持,IMO。我會更新答案來展示這一點。 –

+0

我曾想過這樣做,但它似乎從未將它們分組。當按「年」分組時,我沒有組1組,而是有28組。 – chobo2

0

不,在這種情況下,如果要在切換之前聲明groupTransaction變量,則必須定義具體類型。只有在聲明並立即初始化變量時,纔可以使用具有var關鍵字的匿名類型。

所以,你可以定義將被用於分組的模型:關於使用

dynamic groupTransaction 
+0

確定這就是我雖然什麼。那麼我如何使它具體化呢?我只是去新的MyClassName {A = x.A}}; – chobo2

+0

@ chobo2,我用一個例子更新了我的答案。 –

+0

它是什麼分組的。我想按月份和年份分組,但我幾乎要使用與Transaction相同的類。現在,filterdTransactions有3個屬性(transaction,amount,dollarcap) – chobo2

0

public class MyModel 
{ 
    public int Month { get; set; } 
    public int Year { get; set; } 
} 

,然後與「var」關鍵字。 「var」關鍵字是一個便利關鍵字,它允許您根據所分配的類型隱式聲明變量。你可以實現這個使用幾種方法,包括通用和動態類型。

注意:使用「對象」這種方式被認爲是不好的編碼實踐 你可以只設置變量爲對象:

object groupTransaction = null; 

你也可以把它聲明動態在這種情況下,你失去的IntelliSense支持有的編譯時語法檢查,再加上你可能要轉換的變量在某些情況下:

所有的
dynamic groupTransaction = null; 
0

你不能做什麼

IEnumerable<IGrouping<MyModel, SourceType>> groupTransaction = null; 
DollarCapPeriod dollarCapPeriod = (DollarCapPeriod)Enum.Parse(typeof(DollarCapPeriod), reward.DollarCapPeriod); 
switch (dollarCapPeriod) 
{ 
    case DollarCapPeriod.Monthly: 
     groupTransaction = filterdTransactions.GroupBy(x => new MyModel { x.TransactionDate.Month, x.TransactionDate.Year }); 
     break; 
    case DollarCapPeriod.Yearly: 
     break; 
    default: 
     break; 
} 
相關問題