Method using Func <T, TResult> as parameters

I need help simplifying my method

I have this method

public double ComputeBasicAmount(double basicLimit, double eligibleAmt) { return basicLimit * eligibleAmt; } 

Sample Usage:

 Foo foo = new Foo(100, 1000); double basicAmt = ComputeBasicAmount(foo.BasicLimit, foo.EligibleAmt) 

The problem here is that I want eligibleAmt to be dynamic , because sometimes it’s really not only eligbleAmt that I pass to the method .. like this

 Foo foo = new Foo(100, 1000); double basicAmt = ComputeBasicAmount(foo.BasicLimit, foo.EligibleAmt/foo.RoomRate) 

My solution uses the Func delegate as a parameter, but I don't know how to use it correctly

I want something functional like this

 public double ComputeBasicAmount<T>(double basicLimit, Func<T, double> multiplier) { return basicLimt * multiplier; } double basicAmt = ComputeBasicAmount<Foo>(foo.BasicLimit, x => x.EligibleAmt/x.RoomRate) 

Can someone help me. thanks in advance...

+4
source share
5 answers

If the factor depends on the element, then either you will need to pass this element, or you need to return Func<T, double> :

 public double ComputeBasicAmount<T>(double basicLimit, Func<T, double> multiplier, T item) { return basicLimt * multiplier(item); } ... double basicAmt = ComputeBasicAmount<Foo>( foo.BasicLimit, x => x.EligibleAmt / x.RoomRate, foo) 

or

 public Func<T, double> ComputeBasicAmount<T>(double basicLimit, Func<T, double> multiplier) { return item => basicLimt * multiplier(item); } ... var basicAmtFunc = ComputeBasicAmount<Foo>( foo.BasicLimit, x => x.EligibleAmt / x.RoomRate); var basicAmt = basicAmntFunc(foo); 

If none of them is what you were looking for, explain where you want to provide the actual value of T so that you can work out a factor.

The first is very similar to just Func<double> , to calculate the multiplier, of course ... which, in turn, is pretty much like calling Func<double> when calculating the arguments, to return to the original version, which just takes two doubles.

+4
source

You can declare it simply as Func<double> (this way, you are not creating a method depending on the type of Foo ), and pass any method without taking any parameters and returning double as an argument:

 public static double ComputeBasicAmount(double basicLimit, Func<double> multiplier) { return basicLimit * multiplier(); } 

Some examples of calls:

 class Foo { public double One; public double Two; } Foo f = new Foo(); double result = ComputeBasicAmount(f.One, () => f.Two); 

You may also have some other method returning double

 public static double GetDoubleValue() { return 4.2; } 

... and pass this as an argument:

 double result = ComputeBasicAmount(42,GetDoubleValue); 
+4
source

You would declare your method something like this, so the factor is a delegate that takes a Foo object and returns double:

 double ComputeBasicAmount( double basicLimit, Foo foo, Func<Foo, double> multiplier) 

Then call it like this by passing the lambda to the factor:

 double basicAmt = ComputeBasicAmount( foo.BasicLimit, foo, x => x.EligibleAmt / x.RoomRate); 
0
source

You should use Func<double> as you only use double result

 public double ComputeBasicAmount(double basicLimit, Func<double> multiplier) { return basicLimt * multiplier(); } 

Then name it as follows

 double basicAmt = ComputeBasicAmount<Foo>(foo.BasicLimit, x => x.EligibleAmt/x.RoomRate) 

But then instead you can have the usual double parameter.

0
source

Thanks guys. With your help, I was able to make my existing code more readable and functional ...

  class RNB { public RNB(double roomRate, double roomDays) { RoomRate = roomRate; RoomDays = roomDays; } public double RoomRate { get; set; } public double RoomDays { get; set; } public const double BasicLimit = 100; } class HMS { public double Amount { get; set; } public const double BasicLimit = 200; } public static double ComputeBasicAmount(double basicLimit, Func<double> multiplier) { return basicLimit * multiplier(); } static void Main(string[] args) { RNB rnb = new RNB(100, 2); double result = ComputeBasicAmount(RNB.BasicLimit, () => rnb.RoomDays * rnb.RoomRate); Console.WriteLine("RNB Basic Amt: " + result.ToString()); HMS hms = new HMS() { Amount = 1000 }; result = ComputeBasicAmount(HMS.BasicLimit, () => hms.Amount); Console.WriteLine("HMS Basic Amt: " + result.ToString()); Console.Read(); } 

But I have another problem here. I want to exclude the passage of BasicLimit, because I think it looks superfluous here. Is it possible to put BasicLimit inside the ComputeBasicAmount method

Something like that..

  public static double ComputeBasicAmount<T>(Func<T, double> multiplier, T obj) { return obj.BasicLimit * multiplier(); } 

But I have to put this question in a different thread, because I think its a different topic ... See you guys there ... thanks ...

0
source

All Articles