当没有元素匹配条件时的谓词行为

Ani*_*esh 0 c# linq

当我尝试这个:

Month1Value = 
    g.Where(i => DateTime.ParseExact(i.Period, fmt, cult).Month == lastMonth)
    .FirstOrDefault()
    .Value
Run Code Online (Sandbox Code Playgroud)

如果上个月有数据,我得到的Value分配就好了.如果没有值,我会得到这个例外:

你调用的对象是空的

但是,如果我将以上内容更改为:

Month1Value = 
     g.Where(i => DateTime.ParseExact(i.Period, fmt, cult).Month == lastMonth)
     .Select(x=>x.Value)
     .FirstOrDefault()
Run Code Online (Sandbox Code Playgroud)

如果没有匹配元素,我会得到零,就像我想要的那样.

这两种写lambda表达式的方法有什么区别?

SSCCE:

void Main() {
    var currentMonth = DateTime.Now.Month;
    var currentTimeStamp = DateTime.Now;

    int lastMonth = currentTimeStamp.AddMonths(-1).Month; // 9

    System.Globalization.CultureInfo cInfo = new System.Globalization.CultureInfo("en-US");
    System.Globalization.DateTimeFormatInfo english = cInfo.DateTimeFormat;
    var cult = System.Globalization.CultureInfo.InvariantCulture;
    string fmt = "yyyyMM";

    var DataResults = new[] {
        new Data() {Desc="Item Name", Seq=10639, Period="200906", Value=1.65M},
        new Data() {Desc="Item Name", Seq=10639, Period="200907", Value=1.56M},
        new Data() {Desc="Item Name", Seq=10639, Period="200905", Value=1.62M},
        new Data() {Desc="Item Name", Seq=10639, Period="200908", Value=1.6M}
    };

    var pivotedResults =
        DataResults
        .GroupBy(i => new { i.Desc, i.Seq })
        .Select((g, k) => new PivotedData
        {
            Desc = g.Key.Desc,
            Seq = g.Key.Seq,
            // Month1Value = g.Where(i => DateTime.ParseExact(i.Period, fmt, cult).Month == lastMonth).FirstOrDefault().Value,
            Month1Value = g.Where(i => DateTime.ParseExact(i.Period, fmt, cult).Month == lastMonth).Select(x => x.Value).FirstOrDefault(),
            Month1 = english.GetAbbreviatedMonthName(lastMonth),
        }).ToList();    

    DataResults.Dump();
    pivotedResults.Dump();
}

public class Data {
   public string Desc { get; set; }
   public long Seq { get; set; }
   public string Period { get; set; }
   public decimal Value { get; set; }
}

public class PivotedData {
   public string Desc { get; set; }
   public long Seq { get; set; }
   public string Month1 { get; set; }
   public decimal? Month1Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ser 6

那么答案很简单.

在第一个版本中,您有一个电话.FirstOrDefault().和FirstOrDefault()回报null(请参阅MSDN)为对象,如果没有的元素.然后你尝试调用.Value空指针.

在第二个版本中,它是最后一次调用,在此之前Select()将可枚举变为int-enumerable,默认为intis 0.