0

There are two DTO records:

public record struct DateHour(int Hour, double? Value);
private record struct HourSnapshot(uint TotalSeconds, double? Value);

I have another method which works with enum. I just provide a hand of switch expression for brevity:

HistoryType.LastValueChange => GetTagHourHistory(tagID, scannerName!, dateTime, true)
          .OrderBy(hs => hs.TotalSeconds).Aggregate(null,
            (lastChange, current) => (lastChange is HourSnapshot hs && hs.Value != current.Value) 
              ? lastChange with { TotalSeconds = current.TotalSeconds, Value = current.Value }
              : current,
            aggrResult => (aggrResult is not null)
              ? new DateTime(dateTime.Year, dateTime.Month, dateTime.Day) + TimeSpan.FromSeconds(hs.TotalSeconds)
              : null),

What it does is looking through the IEnumerable from GetTagHourHistory method and tries to find the last value change for the tag in a data source.

I get a compiller error which says "try to explicitly define arguments type". As soon as I change the call to Aggregate<DateHour?>, it fails with error "no overload has three arguments".

According to MSDN there is an overload with resultSelector predicate:

public static TResult Aggregate<TSource,TAccumulate,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate,TSource,TAccumulate> func, Func<TAccumulate,TResult> resultSelector);

It suspect the null seed value for my aggregation, but the only thing to be done, once again, according to MSDN, using explicit type notation is erroneuos.

3
  • "using explicit type notation is erroneuo": citation please! There are plenty of occasions that type arguments cannot be inferred and are thus used.
    – Richard
    Commented Jul 3 at 9:10
  • @Richard in this particular case? Commented Jul 3 at 9:15
  • You said "According to MSDN": where in MS Learning (given MSDN only exists for redirects)? Eg. link to page that says using explicit type parameters is an error.
    – Richard
    Commented Jul 3 at 10:26

2 Answers 2

0

First you can make sure the lastChange can be null, use HourSnapshot? as the seed type. then also make sure that it works with HourSnapshot? and HourSnapshot and it returns the correct type which is DateTime?.

you can use something like this to archive the expected output.

This code has not been tested,

HistoryType.LastValueChange => GetTagHourHistory(tagID, scannerName!, dateTime, true)
    .OrderBy(hs => hs.TotalSeconds)
    .Aggregate<HourSnapshot?, HourSnapshot?, DateTime?>(
        null,
        (lastChange, current) => (lastChange is HourSnapshot hs && hs.Value != current.Value)
            ? lastChange with { TotalSeconds = current.TotalSeconds, Value = current.Value }
            : current,
        aggrResult => (aggrResult is HourSnapshot hs)
            ? new DateTime(dateTime.Year, dateTime.Month, dateTime.Day) + TimeSpan.FromSeconds(hs.TotalSeconds)
            : null
    ),
1
  • unfortunately it doesn't work. Same CS0411 problem Commented Jul 3 at 9:24
0

By specifying Aggregate<DateHour?>, you invoke this overload of the Aggregate method:

public static TSource Aggregate<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,TSource,TSource> func);

This overload only takes one input argument (Func<TSource,TSource,TSource> func) besides source.

The overload you are directly referring to

public static TResult Aggregate<TSource,TAccumulate,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate,TSource,TAccumulate> func, Func<TAccumulate,TResult> resultSelector);

needs three arguments types: TSource, TAccumulate and TResult.

Not the answer you're looking for? Browse other questions tagged or ask your own question.