使用Func <t,tresult>作为参数的方法</t,tresult>

时间:2010-09-10 05:10:11

标签: c# delegates functional-programming

我需要一些关于简化方法的帮助

我有这个方法

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

样本用法:

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

这里的问题是我希望qualifiedAmt是动态,因为有时候 它不仅仅是eligbleAmt我传递给方法 ..就像这样

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

我的解决方案是使用 Func 委托作为参数,但我不知道如何正确使用它

我想要像这样的功能

public double ComputeBasicAmount<T>(double basicLimit, Func<T, double> multiplier)
{

 return basicLimt * multiplier;
}

double basicAmt = ComputeBasicAmount<Foo>(foo.BasicLimit, x => x.EligibleAmt/x.RoomRate)
有人可以帮助我。提前谢谢......

5 个答案:

答案 0 :(得分:5)

如果乘数取决于项目,那么要么你也需要传递项目,你需要返回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)

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

如果这些都不是您想要的,请说明您希望提供T实际值的位置,以便您可以计算乘数。

第一个非常类似于只有一个Func<double>来计算乘数,当然......这反过来就像调用那样计算Func<double>争论,回到原来的版本只需要两个双打。

答案 1 :(得分:4)

您可以将其简单地声明为Func<double>(这样您不会使该方法依赖于Foo类型),并传递任何不带参数的方法并返回double作为参数:< / p>

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

一些示例电话:

class Foo
{
    public double One;
    public double Two;
}


Foo f = new Foo();
double result = ComputeBasicAmount(f.One, () => f.Two);

您还可以使用其他方法返回double

public static double GetDoubleValue()
{
    return 4.2;
}

...并将其作为参数传递:

double result = ComputeBasicAmount(42,GetDoubleValue);

答案 2 :(得分:0)

你声明你的方法是这样的,所以乘数是一个委托,它接受一个Foo对象并返回一个double:

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

然后像这样调用它,将lambda传递给乘数:

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

答案 3 :(得分:0)

您应该使用Func<double>,因为您只使用双重结果

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

然后像这样称呼它

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

但是你可以改为使用常规的双参数。

答案 4 :(得分:0)

谢谢大家,在您的帮助下,我能够使现有代码更具可读性和功能性......

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

但我在这里有另一个问题..我想消除BasicLimit的传递,因为我认为这看起来多余。是否可以将BasicLimit放在ComputeBasicAmount方法

像这样......

 public static double ComputeBasicAmount<T>(Func<T, double> multiplier, T obj)
  {

      return obj.BasicLimit * multiplier();
  }

但是我必须将这个问题放在另一个主题中,因为我认为它是另一个话题...... 在那里见到你们......谢谢......