Reputation: 16532
I have an object like this:
public class Sheet
{
public decimal? Value1 { get; set; }
public decimal? Value2 { get; set; }
}
I have a linq query that builds a list of Tuple<int, Sheet>
. The int is a percentage value stored in our database. This could be a wrapper class, but for simplicity I am using a Tuple.
Then I have an extension method
public static decimal CalculateValue(this List<Tuple<int, Sheet>> sheets, Expression<Func<Tuple<int, Sheet>, decimal?>> field)
{
//return sum of int / 100 * field
}
What I want to do is call something like this (list actually built from objects using linq)
List<Tuple<int, Sheet>> sheets = new List<Tuple<int, Sheet>>();
var value1 = sheets.CalculateValue(x => x.Value1);
var value2 = sheets.CalculateValue(x => x.Value2);
I do not want to use reflection. I do not want "magic" strings for the properties Value1
or Value2
. Is there a way for my extension method to grab the property using the expression and then multiply it by the percentage, and then sum the result across the collection?
Upvotes: 0
Views: 251
Reputation: 236188
According to API which you are trying to build, you should pass property selector for Sheet
object, not for Tuple<int, Sheet>
. You also can use simple Func
delegate instead of expression, because you are working with in-memory objects.
It's not clear how you are going to handle null values - it definitely makes no sense to multiply by null, so I just use zero instead of null (such values will not affect sum):
public static decimal CalculateValue(
this List<Tuple<int, Sheet>> sheets, Func<Sheet, decimal?> field)
{
return sheets.Sum(t => t.Item1 * field(t.Item2).GetValueOrDefault() / 100);
}
Keep in mind - when you apply division operator on two integers, integer division is used. If Item1
value is less than 100
, this division will produce 0
as result. That's why I put multiplication operator first.
Upvotes: 1