关于Func和Action的代码

时间:2012-08-21 22:20:34

标签: c#

http://simpleprogrammer.com/2010/09/24/explaining-what-action-and-func-are/

上面的代码简单地解释了Action和Func。 我仍然无法获得100%的收益。或者无法让代码对我有用。

public void SteamVegetable(Vegetable vegetable, int timeInMinutes)
{
    CookVegetable(vegetable, Steam, timeInMinutes);
}

public void FryVegetable(Vegetable vegetable, int timeInMinutes)
{
    CookVegetable(vegetable, Fry, timeInMinutes);
}

public void BakeVegetable(Vegetable vegetable, int timeInMinutes)
{
    CookVegetable(vegetable, Bake, timeInMinutes);
}

public void CookVegetable(Vegetable vegetable,
   Action<Vegetable, CookingTime> cookingAction,
   int timeInMinutes)
{
    Clean(vegetable);
    cookingAction(vegetable, Minutes.Is(timeInMinutes));
    Serve(vegetable);
}

有人可以帮助我将代码从蔬菜转换为数字和Steam - &gt;加法,弗莱 - &gt;乘法,烘焙 - &gt;当两个操作数传递给它时减法。

当我看到代码正常工作时,我可以更好地理解它。

3 个答案:

答案 0 :(得分:0)

我理解你想要的东西可能是错的,但我会尽力回答。注意,我在示例中省略了许多复杂的东西,比如我会使用泛型而不是普通的int值,但这只会在示例中创建冗余复杂性。

在下面的示例中,我只定义了高阶函数,它接受两个int值,即函数,将两个值转换为字符串(即封装一些行为),并将这个结果包含在封闭和打开标记中,其中一个被传递注意,我假设你熟悉C#中的lambda表示法。

ApplyAndPrettyPrint(100, 3, "summ of 100 and 3 is equal to: ", (x,y) => (x*y).ToString("N0"));
ApplyAndPrettyPrint(100, 3, "100 to power 3 is:  ", (x,y) => (Math.Pow(x,y)).ToString("N0"));
ApplyAndPrettyPrint(2, 33, "2 * root of 33 is:  ", (x,y) => (x * Math.Sqrt(y)).ToString("N0"));

public void ApplyAndPrettyPrint( int firstNumber, int secondNumber, string startTag, Func<int, int, string> evaludationFunction) 
{
    string result = startTag;
    result += evaludationFunction(firstNumber, secondNumber);
    result += ";";
    Console.WriteLine (result);
}

这样Func就像一个盒子一样使用,两个整数作为输入,一个字符串作为输出。

第二个示例显示了我们如何将Action传递给方法,该方法将通过某些数字数组进行评估。再次,我省略了IEnumerable接口和泛型的细节。

int[] numbers = new []{ 1, 2, 4, 5, 6, 7 };
ApplyForEach(numbers, (x) => Console.WriteLine ("square of {0} is {1}", x, x*x));

public void ApplyForEach(int[] numbers, Action<int> someFunction)
{
    foreach (var number in numbers)
    {
        someFunction(number);
    }
}

结果将只打印具有一些描述性字符的整数的正方形。换句话说,Action是委托,没有输出。您可以将它们视为具有某些输入的框,但根本没有输出。

希望这可以帮助您理解。最重要的是,ActionFunc的委托类型之间的唯一区别是最后一个泛型类型的语义:在Func中它是返回值,在Action中返回值是void,所以最后一般type只是输入参数。

如果你觉得这个话题有些困难,Jon Skeet在他的奇妙书“C# in Depth”中描述了第5章“快速跟踪代表”中的代表

答案 1 :(得分:0)

在您提供的示例中,FrySteamBake可能应该是方法。

基本上,ActionFunc允许您将一大块代码传递给方法,然后执行该代码块。

所以,你可以做到

public void Foo(Action<int> actionToPerform, int someInt)  
{
    actionToPerform(someInt);
}

然后,您可以将Foo方法与任何带有整数的“代码块”一起使用。

所以,

public void Bar() 
{
     Action<int> writeToConsole = i =>  { Console.WriteLine(i); }
     Action<int> writeToSomeLogger = i => { Logger.WriteLog(i); }
     Foo(writeToConsole, 10);
     Foo(writeToSomeLogger, 100);
}

答案 2 :(得分:0)

我要把我的例子扔进去......我试着让它变得简单,所以希望这会有所帮助。

以此为例:

class MathClass {
    public int Add(int number1, int number2) {
        return DoSomeMathOperation(number1, number2, theAddingIsActuallyDoneHere); // The method "theAddingIsActuallyDoneHere" below is what gets called.
    }

    private int theAddingIsActuallyDoneHere(int number1, int number2) {
        return number1 + number2;
    }

    public int Multiply(int number1, int number2) {
        return DoSomeMathOperation(number1, number2, theMultiplicationIsDoneHere); // The method "theMultiplicationIsDoneHere" is what gets called.
    }

    private int theMultiplicationIsDoneHere(int number1, int number2) {
        return number1 * number2;
    }

    public int DoSomeMathOperation(int number1, int number2, Func<int, int, int> mathOperationFunc) {
        return mathOperationFunc(number1, number2); // This is where you call the method passed in above.
    }
}

上面的代码可以像这样使用:

MathClass mathClass = new MathClass();

Console.WriteLine(mathClass.Add(5, 10)); // displays 15
Console.WriteLine(mathClass.Multiply(5, 5)); // displays 25

想象一下,你需要一个减法方法。您可以通过DoSomeMathOperation函数创建一个函数,该函数需要Func<int, int, int>,这是一个“获取2个整数参数并返回整数”的函数。这将实现如下:

Console.WriteLine(mathClass.DoSomeMathOperation(100, 50, (num1, num2) => num1 - num2)); // displays "50"

在上面的代码中,您将数字100和50传递给DoSomeMathOperation方法,并将这两个参数传递到Func<int, int, int>。然后返回结果。

..希望这是有道理的..