简体   繁体   English

c# 无法转换匿名类型十进制? [] 到十进制数组

[英]c# Cannot convert anonymous type decimal? [] to decimal array

I am have implemented ac# linq expression which returns a decimal nullable array.我已经实现了 ac# linq 表达式,它返回一个十进制可为空的数组。 I basically need to pass it to a function that accepts decimal array我基本上需要将它传递给一个接受十进制数组的函数

I am getting error我收到错误

Cannot convert anonymous type decimal?无法转换匿名类型十进制? [] to decimal array. [] 到十进制数组。

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);

The method that accepts decimal array接受十进制数组的方法

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

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

First, you don't want a collection of an anonymous type:首先,您不想要匿名类型的集合:

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

You just want the decimal:你只想要小数:

.Select(x => x.Mtd)

But furthermore, it's also telling you that Mtd is a decimal?但此外,它还告诉你Mtd是一个decimal? , not a decimal . ,不是decimal The former can not be directly converted to the latter because the former supports values the latter does not.前者不能直接转换为后者,因为前者支持后者不支持的值。 (ie null ) (即null

So either you'll need to define a default value when Mtd is null :因此,当Mtdnull时,您需要定义一个默认值:

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

or change your method to accept a decimal?[] :或更改您的方法以接受decimal?[]

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

Note that in that last case you will also need to update your method to support a null value.请注意,在最后一种情况下,您还需要更新您的方法以支持null值。 For example, changing the type to which you case 1 in the Aggregate() call:例如,在Aggregate()调用中更改案例1的类型:

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

When you call new { x.Mtd } , you are instructing the compiler to create a new, anonymous type which as a single property, called Mtd , which contains the decimal value.当您调用new { x.Mtd } ,您是在指示编译器创建一个新的匿名类型,该类型作为单个属性,称为Mtd ,其中包含十进制值。 Naturally, this isn't a decimal[] , it's a MyType[] .当然,这不是decimal[] ,而是MyType[]

Since it doesn't seem like you're actually using that anonymous type for anything, you should simply return the decimal value itself, instead of the anonymous type:由于看起来您实际上并未将匿名类型用于任何内容,因此您应该简单地返回十进制值本身,而不是匿名类型:

.Select(x => x.Mtd)

.Select(x => new { x.Mtd}) create a new anonymous object. .Select(x => new { x.Mtd})创建一个新的匿名对象。 You just want the property value:您只需要属性值:

.Select(x => x.Mtd)

If Mtd can be null and you wish to filter out the null values, use this:如果Mtd可以为 null 并且您希望过滤掉 null 值,请使用以下命令:

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

You have to make two changes:您必须进行两项更改:

First remove anonymous type.首先删除匿名类型。 Then for select然后选择

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

This will allow you to pass decimal[] as paramter without changing the current method.这将允许您在不更改当前方法的情况下将 decimal[] 作为参数传递。

Else, you have to do:否则,你必须这样做:

 .Select(x =x.Mtd) 

And change the method parameter to have nullable decimal array.并将方法参数更改为具有可为空的十进制数组。 Hope it is ok希望没事

In addition to my earlier comment, viz除了我之前的评论,即

assuming x.Mtd is decimal , then just remove the new {} ie (x => x.Mtd).ToArray()假设x.Mtddecimal ,那么只需删除new {}(x => x.Mtd).ToArray()

The bigger problem though is that your database has nulls in it, when it really shouldn't - the consequences of a null index performance in a for a period in a compound returns chart would be catastrophic for the compound returns - a missing data point would invalidate all future data points.但更大的问题是您的数据库中有空值,而实际上不应该 - 复合回报图表中一段时间​​内的null索引性能的后果对于复合回报将是灾难性的 - 丢失的数据点会使所有未来的数据点无效。

So the real solution is to find any null datapoints in the data source and provide the correct data for them.所以真正的解决方案是在数据源中找到任何空数据点并为它们提供正确的数据。

Then change the data type of Mtd on the Dto returned from GetViewService from然后将GetViewService返回的GetViewServiceMtd的数据类型从

 decimal? Mtd 

to

decimal Mtd

(ie disallow nulls). (即不允许空值)。

Then all that is needed to your original code is to remove the anonymous class projection, ie那么您的原始代码所需要做的就是删除匿名类投影,即

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

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

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