C# 在这种情况下我可以使用匿名类型吗?

C# 在这种情况下我可以使用匿名类型吗?,c#,C#,我有这个密码 // was before var groupTransactions; IEnumerable<IGrouping<TransactionsGroupedByMonthYear, TransactionDto>> groupTransactions = null; DollarCapPeriod dollarCapPeriod = (DollarCapPeriod)Enum.Parse(typeof(DollarCapPeriod), rew

我有这个密码

   // 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;
}
编辑

目前,我正试图做现在使用一个具体的支持,但我需要通过两种不同的方式过滤。有时我只需要“年”,有时我需要“月”和“年”


我不知道怎么做。它们都需要放在同一个变量中,因此它们需要是相同的类型。

否,在这种情况下,如果要在切换之前声明
groupTransaction
变量,则必须定义一个具体的类型。只有在声明并立即初始化变量时,才能使用带有var关键字的匿名类型

因此,您可以定义一个用于分组的模型:

public class MyModel
{
    public int Month { get; set; }
    public int Year { get; set; }
}
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;
}
然后:

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;
}
IEnumerable groupTransaction=null;
DollarCapPeriod DollarCapPeriod=(DollarCapPeriod)Enum.Parse(typeof(DollarCapPeriod),reward.DollarCapPeriod);
开关(dollarCapPeriod)
{
每月出现的案例数量:
groupTransaction=filterdTransactions.GroupBy(x=>new MyModel{x.TransactionDate.Month,x.TransactionDate.Year});
打破
每年出现的病例数:
打破
违约:
打破
}
使用

dynamic groupTransaction

使用“var”关键字不能这样做。“var”关键字是一个方便的关键字,它允许您根据所分配的类型隐式声明变量。您可以使用包括泛型和动态类型在内的多种方法来实现这一点

注意:以这种方式使用“object”被认为是糟糕的编码实践 您可以将变量设置为对象:

object groupTransaction = null;
您还可以将其声明为动态,在这种情况下,您将失去intellisense支持和一些编译时语法检查,此外,在某些情况下,您可能必须强制转换该变量:

dynamic groupTransaction = null;

首先,不要混淆匿名类型和推断类型。
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
,在您的情况下,只有
TKey
是匿名的。虽然在代码中声明该类型是可能的,但这是非常困难的,需要声明临时变量,以便从中获取匿名的
typeof()
信息。几乎可以肯定,这将是一个无法维持的混乱局面

相反,您应该只声明一个用于组键的类型。由于嵌套的泛型,它仍然会很难看,但远没有尝试使用匿名类型那么糟糕

public class TransactionGroup
{
  public int Month;
  public int Year;
}
并获得您的分组:

public class MyModel
{
    public int Month { get; set; }
    public int Year { get; set; }
}
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;
}
IEnumerable groupTransaction;
var period=(period)Enum.Parse(typeof(period),record.period);
转换(周期)
{
个案期间。每月:
groupTransaction=transactions.GroupBy(x=>new TransactionGroup
{
月=x.TransactionDate.Month,
年份=x.TransactionDate.Year
});
打破
案件期间。每年:
groupTransaction=transactions.GroupBy(x=>new TransactionGroup
{                 
月份=0,
年份=x.TransactionDate.Year
});
打破
违约:
打破
}

好的,我就是这么想的。那么我如何使它具体化呢?我是否只需要使用新的MyClassName{A=x.A};按什么分组。我想按月份和年份分组,但我将使用事务所在的类。现在filterdTransactions有3个属性(transaction、amount、dollarcap)作为我想要按“年”分组的年度属性。我可以使用MyModel进行分组,而不设置“月”吗?好的,那么我的年度开关如何呢。我只想按年份对它进行分组,但仍然使用groupTransaction存储它。只是在某些情况下,我需要按月份和年份分组,有时只是按年份分组。我想建立一些存储linq的东西(认为它会起作用),然后在切换后将其传递给group by,但我不知道如何做。最简单的选择是按月份对所有内容进行分组=0,因为您对实际月份不感兴趣。有些人可能会说“幻数”方法是错误的,但替代方法的可维护性要差得多,我会更新答案来说明这一点。我曾想过这样做,但它似乎从未将它们分组。当按“年”分组时,我没有分组1组,而是有28个组。如果你得到的组数不正确,你需要查看组键的值,看看它们为什么不同。在我的列表中,我有许多不同的月份。我想他们当时不会分组。我不关心这个场景中的月份,但它们可能被设置为所有不同类型的月份。