从我的last question开始,我得到了List<double?>
类型的列表,需要将其传递给仅接受List<Double>
的方法。我目前遇到错误,无法将IEnumerable<double?>
转换为IEnumerable<double>
。如果您注意到下面的方法AverageGain
仅接受IEnumerable<double>
。
如何解决此错误?
Dictionary<int, IEnumerable<double>> returnsList = new Dictionary<int, IEnumerable<double>>();
(double Monthly, double Annual) averageGain;
trackRecordVm = trackRecord.TrackRecord;
fundId = trackRecord.FundId;
var jan = trackRecordVm.Select(x => x.Jan).ToList();
var feb = trackRecordVm.Select(x => x.Feb).ToList();
var mar = trackRecordVm.Select(x => x.Mar).ToList();
var apr = trackRecordVm.Select(x => x.Apr).ToList();
var may = trackRecordVm.Select(x => x.May).ToList();
var jun = trackRecordVm.Select(x => x.Jun).ToList();
var jul = trackRecordVm.Select(x => x.Jul).ToList();
var aug = trackRecordVm.Select(x => x.Aug).ToList();
var sep = trackRecordVm.Select(x => x.Sep).ToList();
var oct = trackRecordVm.Select(x => x.Oct).ToList();
var nov = trackRecordVm.Select(x => x.Nov).ToList();
var dec = trackRecordVm.Select(x => x.Dec).ToList();
var monthData = new List<double?>();
monthData.AddRange(jan);
monthData.AddRange(feb);
monthData.AddRange(mar);
monthData.AddRange(apr);
monthData.AddRange(may);
monthData.AddRange(jun);
monthData.AddRange(jul);
monthData.AddRange(aug);
monthData.AddRange(sep);
monthData.AddRange(oct);
monthData.AddRange(nov);
monthData.AddRange(dec);
returnsList.Add(fundId, monthData);
foreach (KeyValuePair<int, IEnumerable<double?>> entry in returnsList)
{
list1 = new List<Tuple<string, double, double>>();
averageGain = riskMatrix.AverageGain(entry.Value);
list1.Add(new Tuple<string, double, double>("AverageGain", averageGain.Monthly, entry.Annual));
list.Add(entry.Key, list1);
}
public (double Monthly, double Annual) AverageGain(IEnumerable<double> ReturnsList)
{
double returnList = ReturnsList.GainMean();
return (Monthly: returnList, Annual: returnList * Math.Pow(12, 0.5));
}
答案 0 :(得分:2)
您可以使用returnList.Select(v => v.Value)
访问可为空值的值。
这使用System.Linq。
在您的特定示例中,您将得到以下结果:
averageGain = riskMatrix.AverageGain(entry.Value.Select(v => v.Value));
对于IEnumerable中为null的情况,防止这种情况的发生也很重要,例如:
averageGain = riskMatrix.AverageGain(entry.HasValue ? entry.Value : 0D);
如果存在空entry
的可能性,那么您将需要进行更多检查,但是我敢肯定,这不在此问题的范围内。
答案 1 :(得分:1)
double?
可以是null
,因此在该类型和double
之间没有显式转换(您对空值怎么办?),但是{{ 1}}结构是具有两个有用的方法/属性的:Nullable<T>
和HasValue
。
GetValueOrDefault
如果已为对象分配了值(非null),则返回HasValue
;如果true
返回了GetValueOrDefault
的值,则返回double
,否则返回类型的默认值(在0
的情况下为double
。
因此,您可以返回所有已分配的值,也可以获取所有0
项目的默认值(null
)的值:
List<double?> nullables = new List<double?> {1, null, 2, null, 3};
// This will contain {1, 2, 3}
List<double> values = nullables
.Where(item => item.HasValue)
.Select(item => item.Value)
.ToList();
// This will contain {1, 0, 2, 0, 3}
List<double> valuesAndDefaults = nullables
.Select(item => item.GetValueOrDefault())
.ToList();
答案 2 :(得分:0)
如上所述,但是有两种方法可以实现:
returnList.Where(f => f.HasValue).Select(f => f.Value);
为您提供所有拥有数据和
的月份returnList.Select(f => f.GetValueOrDefault());
在一个月没有值的地方返回0。