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

时间:2012-01-19 23:45:22

标签: c#

我有这段代码

   // 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

修改

目前我正在尝试使用具体的支持,但我需要通过2种不同的方式进行过滤。有时我只需要“年”,有时我需要“月”和“年”

我不知道该怎么做。他们都需要进入相同的变量,因此它们需要是相同的类型。

4 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

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

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

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

然后:

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

答案 2 :(得分:0)

使用

怎么样?
dynamic groupTransaction

答案 3 :(得分:0)

使用“var”关键字无法做到这一点。 “var”关键字是一个便捷关键字,允许您根据所分配的类型隐式声明变量。您可以使用多种方法实现此目的,包括通用和动态类型。

注意:使用'object'这种方式被认为是错误的编码习惯 您可以将变量设置为对象:

object groupTransaction = null;

你也可以声明它是动态的,在这种情况下你会失去intellisense支持和一些编译时语法检查,而且你可能必须在某些情况下转换变量:

dynamic groupTransaction = null;