繁体   English   中英

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

[英]Can I use an anonymous type in this situation?

我有这个代码

   // 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种不同的方式进行过滤。 有时我只需要“年”,有时我需要“月”和“年”

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

首先,不要将匿名类型与推断类型混淆。 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;
}

不,在这种情况下,如果要在切换之前声明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;
}

那使用呢

dynamic groupTransaction

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

注意:以这种方式使用“对象”被认为是不好的编码习惯,您可以将变量设置为对象:

object groupTransaction = null;

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

dynamic groupTransaction = null;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM