C#不能转换匿名类型十进制? []转换为十进制数组

时间:2019-04-10 13:04:46

标签: c#

我已经实现了一个c#linq表达式,该表达式返回一个可为空的十进制数组。我基本上需要将其传递给接受十进制数组的函数

我遇到错误

  

无法转换匿名类型十进制? []转换为十进制数组。

var benchMark1Returns = GetViewService<MV_INDEX_PERFORMANCE>()
    .Where(x => x.IndexId == benchMark1 && x.PriceDate.Year == year)
    .Select(x => new { x.Mtd}).ToArray();

var benchMark2Returns = GetViewService<MV_INDEX_PERFORMANCE>()
    .Where(x => x.IndexId == benchMark2 && x.PriceDate.Year == year)
    .Select(x => new { x.Mtd }).ToArray();

var compoundReturnsBenchMark1 = CompoundReturns(benchMark1Returns);

接受十进制数组的方法

public static decimal? CompoundReturns(decimal[] rtns)
{
    if (rtns.Length == 0)
        return null;

    return rtns.Aggregate((decimal)1, (acc, val) => acc * (1 + val)) - 1;
}

5 个答案:

答案 0 :(得分:3)

首先,您不需要匿名类型的集合:

.Select(x => new { x.Mtd })

您只需要小数:

.Select(x => x.Mtd)

此外,它还告诉您Mtddecimal?,而不是decimal。前者不能直接转换为后者,因为前者支持后者不支持的值。 (即null

因此,当Mtdnull时,您将需要定义一个默认值:

.Select(x => x.Mtd ?? 0M)

或更改您的方法以接受decimal?[]

public static decimal? CompoundReturns(decimal?[] rtns)

请注意,在最后一种情况下,您还需要更新您的方法以支持null值。例如,在1调用中将Aggregate()的大小写更改为以下类型:

rtns.Aggregate((decimal?)1, (acc, val) => acc * (1 + val)) - 1;

答案 1 :(得分:2)

当调用new { x.Mtd }时,您正在指示编译器创建一个新的匿名类型,该类型作为单个属性称为Mtd,其中包含十进制值。自然,这不是decimal[],而是MyType[]

由于似乎您实际上并没有使用该匿名类型,因此您应该简单地返回十进制值本身,而不是匿名类型:

.Select(x => x.Mtd)

答案 2 :(得分:1)

.Select(x => new { x.Mtd})创建一个新的匿名对象。您只需要属性值:

.Select(x => x.Mtd)

如果Mtd可以为空,并且您希望过滤掉空值,请使用以下方法:

.Where(x => x.Mtd != null).Select(x => x.Mtd.Value).ToArray();

答案 3 :(得分:0)

您必须进行两项更改:

首先删除匿名类型。然后选择

.Select( x=> x.Mtd ?? 0);

这将允许您在不更改当前方法的情况下将小数点[]作为参数传递。

否则,您必须这样做:

 .Select(x =x.Mtd) 

并更改method参数以具有可为空的十进制数组。 希望没事

答案 4 :(得分:0)

除了我之前的评论,即

  

假设x.Mtddecimal,则只需删除new {},即(x => x.Mtd).ToArray()

但是,更大的问题是您的数据库中实际上不应该包含空值-复合回报图表中一段时间​​内null索引性能的后果对于复合收益而言将是灾难性的返回-丢失的数据点会使所有未来的数据点失效。

因此,真正的解决方案是在数据源中找到任何空数据点,并为其提供正确的数据。

然后更改从{p}返回的Dto上Mtd的数据类型

GetViewService

 decimal? Mtd 

(即不允许null)。

然后,原始代码所需要做的就是删除匿名类投影,即

decimal Mtd