C#中的函数式编程

 

在函数式编程中,可以把函数看作数据。函数也可以作为参数,函数还可以返回函数。比如,LINQ就是基于函数式编程的。

两个例子引出函数式编程


语句式编程可能这样写:

string result;
if(value > 0)
{
    result = "正数";
}
else
{
    result = "负数";
}

 

而使用函数式表达式,可以简化为:

var result = value > 0 "正数":"负数";

 

再来看一个过滤和排序的例子:

var i = 0;
while(i < list.Count)
{
    if(list[i] % 2 != 0)
    {
        list.RemoveAt(i);
    }
    else
    {
        ++i;
    }
}
list.Sort();

 

函数式编程可以写成如下:

from x in list
    where x  % 2 == 0
    orderby x
    select x;

 

list
    .where(x => x % 2 == 0)
    .OrderBy(x => x)

 

可见,在LINQ中,一个表达式(函数)的返回结果作为令一个表达式(函数)的源,还可以进行多个链式。

 

封装一个函数式方法


比如读取远程数据。

void Main()
{
    XDocument timeDoc;
    
    using(var client = new System.Net.WebClient())
    {
        timeDoc = XDocument.Parse(client.DonwloadString(""));
    }
    
    var ms = Convert.ToInt64(timeDoc.Root.Attribute("time").Value) / 1000;
    var currentTime = new DateTime(1977,1,1).AddMilliseconds(ms).ToLocalTime();
    Console.WriteLine(currentTime);
}

 

对于using部分我们可以提炼出一个方法。

private XDocument GetTime()
{
    
    using(var client = new System.Net.WebClient())
    {
        return XDocument.Parse(client.DonwloadString(""));
    }
    
}


void Main()
{
    var timeDoc = GetTime();
    var ms = Convert.ToInt64(timeDoc.Root.Attribute("time").Value) / 1000;
    var currentTime = new DateTime(1977,1,1).AddMilliseconds(ms).ToLocalTime();
    Console.WriteLine(currentTime);   
}

 

但,还不够。以上的GetTime方法只是对WebClient这个实现了IDisposable接口的using语句进行了封装,可不可以对所有实现IDisposable接口的类型的using语句进行封装呢?

 

public static class MyDisposable
{
    public static TResult Using<TDisposable, TResult>(
    Func<TDisposable> factory, 
    Func<TDisposable, TResult> map) 
    where TDisposable : IDisposable
    {
        using(var disposable = factory())
        {
            return map(disposable);
        }
    }
}

void Main()
{
    var time = MyDisposable
        .Using(
            () => new System.Net.WebClient(),
            client => XDocument.Parse(client.DownloadString(""))
        )
        .Root
        .Attribute("time")
        .Value;
        
    var ms = Convert.ToInt64(time) / 1000;
    var currentTime = new DateTime().AddMilliseconds(ms).ToLocalTime();
    Console.WriteLine(currentTime);
}

 

在函数式编程中,函数返回的类型基本上另外一个函数方法的源实例。

posted @ 2016-03-12 23:56  Darren Ji  阅读(2134)  评论(1编辑  收藏  举报

我的公众号:新语新世界,欢迎关注。