C#的委托与JavaScript的函数式编程

本文探讨了函数式编程的概念,并通过C#与JavaScript对比展示了如何利用委托和函数作为参数进行计算方法的选择。介绍了C#中delegate的使用方法及JavaScript中函数式编程的灵活性。
作者: 0009

看这么一个实例:
计算两个数字,返回一个结果,计算方法未知,可以是相加,相减,相乘,相除等等.
该模型就是: Compute(x, y, ComputeMethod)
Compute方法需要三个参数, x, y两个数字,和一个执行计算的方法ComputeMethod.

用了解决此类问题,于是,C++中有了函数指针,C#中有了委托,而做为支持函数式编程的JavaScript更为彻底,函数(方法)的本质上就是一个变量,变量能怎么传,他就能怎么传.

注: JavaScript是目前计算机语言中极少数能支持函数式编程的语言之一, 函数式编程!=面向函数编程,是一种比面向对象更为抽象,更为接近数学本质的编程方法.以后我会给你讲这方面内容.

C++我就不讲了,我们先看一下这个问题用C#是怎么解决的.
因为C#是强类型的,你必须规定好了ComputeMethod的内容,比如有没有返回值,有几个参数,他才让你传递,因此C#的设计者就必须想出一个安全合理的解决方案.
┏━━━━━━━━━━━━━━━━━━┓
┃Add, Subtract, Multiply, Divide ....┃
┗━━━━━━━━━━━━━━━━━━┛
    │
    │ ┏━━━━━━━━━━━━━━┓
    ↓─┃通过一个中间载体,即delegate┃
    │ ┗━━━━━━━━━━━━━━┛
    ↓
┏━━━━━━━┓ ┏━━━━━━━━━━━━━━┓
┃ComputeMethod ┃→┃Compute(x, y, ComputeMethod)┃
┗━━━━━━━┛ ┗━━━━━━━━━━━━━━┛

首先我们声明一个中间载体:delegate int ComputeMethod(int x, int y);
这个委托有什么含义呢?
1.委托本质上是一个类,一个特殊的类,这个类继承于System.MulticastDelegate,其特殊行为你可以以后再深入研究,你只要用类的标准来看待delegate就行了.
2.这个委托规定好了"ComputeMethod"的内容:接受两个int参数,并返回一个int.

好,有了这个委托我们就可以写Compute方法了:
int Compute(int x, int y, ComputeMethod method)
{
    // return method.Invoke(x, y);
    return method(x, y);
}
说明:
method(x, y)实质上隐式调用method.Invoke(x, y),当然你可以显式调用method.Invoke(x, y).这样更接近事物的本质,因为"执行委托"的本质是"执行别人委托给他的方法".

我们再来写几个实现:
int Add(int x, int y)
{
    return x + y;
}
int Subtract(int x, int y)
{
    return x - y;
}
int Multiply(int x, int y)
{
    return x * y;
}
int Divide(int x, int y)
{
    return x / y;
}

完整的例子

class Program
{
    delegate int ComputeMethod(int x, int y);
    
    static void Main()
    {
        int x = 9, y = 3;

        ComputeMethod add = new ComputeMethod(Add);
        ComputeMethod subtract = new ComputeMethod(Subtract);
        ComputeMethod multiply = new ComputeMethod(Multiply);
        ComputeMethod divide = new ComputeMethod(Divide);

        Console.WriteLine(ActCompute(x, y, add));
        Console.WriteLine(ActCompute(x, y, subtract));
        Console.WriteLine(ActCompute(x, y, multiply));
        Console.WriteLine(ActCompute(x, y, divide));
    }
    
    static string ActCompute(int x, int y, ComputeMethod method)
    {
        if (method != null)
        {
            // method.Invoke(x, y);
            return String.Format("{0}({1}, {2}) = {3}", method.Method.Name, x, y, method(x, y));
        }
        else
        {
            throw new Exception("Compute Method is null!");
        }
    }
    
    static int Add(int x, int y)
    {
        return x + y;
    }
    
    static int Subtract(int x, int y)
    {
        return x - y;
    }
    
    static int Multiply(int x, int y)
    {
        return x * y;
    }
    
    static int Divide(int x, int y)
    {
        return x / y;
    }
}
查了一下资料,.net2.0中已经支持匿名方法和隐式声明delegate,这两种方式和javascript中的使用方法相似,我写了个例子你参考一下.
 
class Program
{
    delegate int ComputeMethod(int x, int y);
    static void Main()
    {
        int x = 9, y = 3;
        //ComputeMethod add = new ComputeMethod(Add);
        ComputeMethod subtract = new ComputeMethod(Subtract);
        ComputeMethod multiply = new ComputeMethod(Multiply);
        //ComputeMethod divide = new ComputeMethod(Divide);
        Console.WriteLine(ActCompute(x, y, Add)); // 直接调用Program.Add,实际上是隐式声明delegate
        Console.WriteLine(ActCompute(x, y, subtract));
        Console.WriteLine(ActCompute(x, y, multiply));
        Console.WriteLine(ActCompute(x, y, delegate(int x2, int y2) { return x2 / y2; })); // 匿名方法
    }
    static string ActCompute(int x, int y, ComputeMethod method)
    {
        if (method != null)
        {
            // method.Invoke(x, y);
            return String.Format("{0}({1}, {2}) = {3}", method.Method.Name, x, y, method(x, y));
        }
        else
        {
            throw new Exception("Compute Method is null!");
        }
    }
    static int Add(int x, int y)
    {
        return x + y;
    }
    static int Subtract(int x, int y)
    {
        return x - y;
    }
    static int Multiply(int x, int y)
    {
        return x * y;
    }
    //static int Divide(int x, int y)
    //{
    // return x / y;
    //}
}
我们看用支持函数式编程的JavaScript是怎么样来解决这个问题的:
 
首先,写Compute函数:
function Compute(x, y, fun)
{
    return fun(x, y);
}
 
相信这个表达已经相当清晰我不需要再做解释了,在JavaScript中函数也是一种变量,而且JS不是类型安全的语言,所以直接传递就行.
 
写一个实现来试试
function Add(x, y)
{
    return x + y;
}
function Compute(x, y, fun)
{
    return fun(x, y);
}
alert(Compute(9, 3, Add));
 
C#就像刀法,招式严整,深厚有力;而JavaScript更像剑法,灵活轻巧,一剑穿心.
你看看这个问题JS的各种写法:
 
function Add(x, y) // 常规方法
{
    return x + y;
}
var Subtract = function (x, y) // 在面向对象开发时经常用到
{
    return x - y;
}
var Multiply = new Function("x", "y", "return x * y;"); // 实现function的原始方式,但是不推荐,效率很低.
 
function Compute(x, y, fun)
{
    return fun(x, y);
}
alert(Compute(9, 3, Add));
alert(Compute(9, 3, Subtract));
alert(Compute(9, 3, Multiply));
alert(Compute(9, 3, function (x, y){ return x / y; })); // 轻便型的实现方法,小函数时用可用.
 
第四种方法举例:
<span id="s"></span>
<script language="JavaScript">
setInterval(function (){document.getElementById("s").innerHTML=Date();}, 1000);
</script>

转载于:https://www.cnblogs.com/guodapeng/archive/2007/11/13/958320.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值