改变功能的运作方式 [英] Altering the way a function operates

查看:73
本文介绍了改变功能的运作方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hello Code Project Gurus



我知道委托可以使用委托被调用时已知的值进行操作 - 这只是一个参数

例如

Hello Code Project Gurus

I know it is possible to have delegates operate with values that are known at the time the delegate is called - that's simply a parameter
e.g.

   Func<double, double> areaOfCircle = r => Math.PI * Math.Pow(r, 2); 
   Func<double, double> diameterOfCircle = r => 2 * Math.PI * r;
   
   var iNeed = diameterOfCircle;
// -----------------------------
   Console.WriteLine(iNeed(5));    // output is 31.4159265358979
   Console.WriteLine(iNeed(10));   //           62.8318530717959
		
   iNeed = areaOfCircle; 
// ---------------------
   Console.WriteLine(iNeed(5));    // output is 78.5398163397448
   Console.WriteLine(iNeed(10));   //           314.159265358979



我想知道是否有任何方法可以动态创建委托,以便每个委托使用在创建委托时在运行时已知的值进行操作(不是在代表被调用)。



所以,使用上面的例子,有没有办法告诉areaOfCircle使用其他因素而不是pi?类似于


I am wondering if there is any way to dynamically create delegates so that each delegate operates using values that are known at runtime when the delegate is created (not when the delegate is called).

So, using the example above, is there a way tell areaOfCircle to use some other factor rather than pi? Something akin to

   Func<double, double> areaOfCircle = r => ::factor:: * Math.Pow(r, 2); 
   Func<double, double> diameterOfCircle = r => 2 * ::factor:: * r;
   
   var iNeed = diameterOfCircle(factor::3);   
// ----------------------------------------
   Console.WriteLine(iNeed(5));    // output is 30
   Console.WriteLine(iNeed(10));   //           60
		
   iNeed = areaOfCircle(factor::3.14); 
// -----------------------------------
   Console.WriteLine(iNeed(5));    // output is 78.5
   Console.WriteLine(iNeed(10));   //           314



再次,我知道通过将因子传递给Console.WriteLine调用中的每个函数,可以轻松解决这样的简单示例。但相反,想象一下iNeed的赋值和对iNeed的调用是在单独的方法中发生的,甚至是类;一旦iNeed被分配,它就作为返回值传递给一个调用类,它将它放在一个List中,由另一个类调用它来执行函数...正常的,日常类型的东西。



我正在寻找的是一种设置函数的方法,以便在进行iNeed分配时使用某个因子进行操作。这样的事情可能吗?



我尝试过的事情:



搜索网络。

阅读关于代表,匿名代表,动态变量等的MS文档。


Again, I know that a simple example like this is easily solvable by passing the factor to each function in the Console.WriteLine calls. But instead, imagine that the assignment to iNeed and the calls to iNeed are occurring in separate methods, or even classes; that once iNeed is assigned, it is passed as the return value to a calling class that sticks it in a List, which gets called by another class to execute the function... normal, everyday type of stuff.

What I am looking for is a way to set up the functions to operate with a certain factor when the assignment to iNeed is made. Is such a thing possible?

What I have tried:

Searching the net.
Reading MS documentation on delegates, anonymous delegates, dynamic variables, etc.

推荐答案

这样的事情会起作用:

Something like this would work:
Func<double, Func<double, double>> factoredAreaOfCircle = factor => r => factor * Math.Pow(r, 2);
Func<double, Func<double, double>> factoredDiameterOfCircle = factor => r => 2 * factor * r;

Func<double, double> iNeed = factoredDiameterOfCircle(3);
Console.WriteLine(iNeed(5));  // Output is 30
Console.WriteLine(iNeed(10)); // Output is 60
		
iNeed = factoredAreaOfCircle(3.14); 
Console.WriteLine(iNeed(5));  // Output is 78.5
Console.WriteLine(iNeed(10)); // Output is 314



Currying vs部分功能应用Jon Skeet的编码博客 [ ^ ]


您无法在运行时更改委托定义。



代表什么都不是,指向函数的指针。委托的参数列表必须与其指向的函数的参数列表匹配。如果没有,你就可以解除堆栈的不平衡,因为调用正在推动堆栈上的参数,而你正在调用的函数正在将它们从堆栈中弹出而不是按下它们。



这个概念被称为自修改代码,在生产质量代码中很难正确实现。我不推荐这样做。



你真正在谈论的只是在你的函数中添加一个可选参数,其默认值是PI。 br />
You cannot change the delegate definition at runtime.

A delegate is nothing but a pointer to a function. The parameter list of the delegate must match the parameter list of the function that it points to. If it doesn't you can unbalance the stack as the call is pushing parameters on the stack and the function you're calling is popping them off the stack not as they were pushed on.

The concept is called "self modifying code" and is stupid difficult to implement properly in production quality code. I don't ever recommend doing it.

What you are really talking about is just adding an optional parameter to your function, the default value of which is PI.
double CalculateAreaCircle(double r, double factor = Math.PI);


这篇关于改变功能的运作方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆