如何检查List <t>索引是否为空

时间:2017-03-12 19:31:39

标签: c# list indexing

我有一个方法可以计算db中每个月的总金额,如图所示。

 public static List<Sale> ChartMonthlySalePerYear()
    {
        using (SQLiteConnection con = new SQLiteConnection(Connection.DatabaseLocationString))
        {
            SQLiteCommand cmd = null;
            string query = String.Format("SELECT  strftime('%m', SaleDate)  AS  month,  SUM(AmountPaid)  AS  sum_amountpaid   FROM  {0}   WHERE   strftime('%Y', SaleDate)  =  @1  GROUP BY   strftime('%m', SaleDate)  ", Sale.TABLE_NAME);
            cmd = new SQLiteCommand(query, con);
            cmd.Parameters.Add(new SQLiteParameter("@1", Properties.Settings.Default.ChartYearlyDisplay));
            con.Open();
            SQLiteDataReader reader = cmd.ExecuteReader();

            var list = new List<Sale>();
            while (reader.Read())
            {
                Sale value = new Sale()
                {
                    Months = reader["month"].ToString(),
                    SUMAmountPaid = Convert.ToDecimal(reader["sum_amountpaid"])
                };
                list.Add(value);
            }
            con.Close();

            return list;

        }
    }

它会按月返回一个像这样的列表,

  • 01 20000.00(例如1月)
  • 02 13000.00(例如二月)
  • 03 10000.00(例如3月)
  • 04 10000.00(例如四月)
  • 05 10000.00(例如五月)
  • 06 20000.00(例如6月)
  • 07 15000.00(例如7月) 但其他几个月没有销售。

这就是使用方法的地方。

List<Sale> sum = SaleViewModel.ChartMonthlySalePerYear();
                Jan = sum[0].SUMAmountPaid;
                Feb = sum[1].SUMAmountPaid;
                Mar = sum[2].SUMAmountPaid;
                Apr = sum[3].SUMAmountPaid;
                May = sum[4].SUMAmountPaid;
                Jun = sum[5].SUMAmountPaid;
                Jul = sum[6].SUMAmountPaid;
                //For Ausgust
                if (sum[7] != null)
                    Aug = 0;
                else
                    Aug = sum[7].SUMAmountPaid;
                //For September
                if (sum[7] != null)
                    Sep = 0;
                else
                    Sep = sum[7].SUMAmountPaid;

我现在的挑战是,8月和8月没有任何价值。 9月,我想在我给它一个默认值之前先检查,但它抛出一个异常。 Index was out of range. Must be non-negative and less than the size of the collection.八月&amp;九月 提前谢谢。

2 个答案:

答案 0 :(得分:6)

您希望在访问该索引之前检查索引是否小于或等于列表的长度,以避免索引超出范围异常:

if (sum.Count <= 7) 
   Aug = 0;
else
   Aug = sum[7].SUMAmountPaid;

但如果您的数据存在漏洞,那么这项工作就像您期望的那样。如果您在数据中有漏洞,则列表的索引不会与月份匹配。如果是这种情况,请考虑使用Dictionary<int, Sale>()

var salesByMonth = new Dictionary<int, Sale>();
while (reader.Read())
{
    Sale value = new Sale()
    {
        Months = reader["month"].ToString(),
        SUMAmountPaid = Convert.ToDecimal(reader["sum_amountpaid"])
    };
    salesByMonth.Add(int.Parse(value.Months), value);
}

并且

Sale value;
if (salesByMonth.TryGetValue(1, out value))
   Jan = value.SUMAmountPaid;
else
   Jan = 0;

if (salesByMonth.TryGetValue(2, out value))
   Feb = value.SUMAmountPaid;
else
   Feb = 0;

答案 1 :(得分:0)

您不应该对此使用索引方法,因为您的Sale类型具有Months属性,其中填充了reader["month"]值。您可以使用谓词(Func<Sale, bool>委托)确定是否存在月份。

使用Linq,您可以将谓词与FirstFirstOrDefault一起使用,以返回评估为true的第一个实例。

List<Sale> sum = SaleViewModel.ChartMonthlySalePerYear();

Jan = sum.Where((item) => item.Months == 1).Select((item) => item.SUMAmountPaid).DefaultIfEmpty(0).First();
Feb = sum.Where((item) => item.Months == 2).Select((item) => item.SUMAmountPaid).DefaultIfEmpty(0).First();
Mar = sum.Where((item) => item.Months == 3).Select((item) => item.SUMAmountPaid).DefaultIfEmpty(0).First();
Mar = sum.Where((item) => item.Months == 4).Select((item) => item.SUMAmountPaid).DefaultIfEmpty(0).First();

,或者

Jan = sum.Any((item) => item.Months == 1) ? sum.First((item) => item.Months == 1).SUMAmountPaid : 0;
Feb = sum.Any((item) => item.Months == 2) ? sum.First((item) => item.Months == 2).SUMAmountPaid : 0;
Mar = sum.Any((item) => item.Months == 3) ? sum.First((item) => item.Months == 3).SUMAmountPaid : 0;
Apr = sum.Any((item) => item.Months == 4) ? sum.First((item) => item.Months == 4).SUMAmountPaid : 0;

替代地

你可以.ForEach遍历你的记录和一个切换案例来映射它们。

List<Sale> sum = SaleViewModel.ChartMonthlySalePerYear()
    .ForEach((item) => {
        switch(item.Months)
        {
            case 1:
                Jan = item.SUMAmountPaid;
                break;
            case 2:
                Feb = item.SUMAmountPaid;
                break;
            case 3:
                Mar = item.SUMAmountPaid;
                break;
            case 4:
                Apr = item.SUMAmountPaid;
                break;
            case 5:
                May = item.SUMAmountPaid;
                break;
            case 6:
                Jun = item.SUMAmountPaid;
                break;
            case 7:
                Jul = item.SUMAmountPaid;
                break;
            case 8:
                Aug = item.SUMAmountPaid;
                break;
            case 9:
                Sept = item.SUMAmountPaid;
                break;
            case 10:
                Oct = item.SUMAmountPaid;
                break;
            case 11:
                Nov = item.SUMAmountPaid;
                break;
            case 12:
                Dec = item.SUMAmountPaid;
                break;
            default: //do nothing
                break;
        }
    });

默认情况下确保JanDec0