C#中的函数式编程

时间:2023-03-09 23:26:36
C#中的函数式编程

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

两个例子引出函数式编程

语句式编程可能这样写:

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

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

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

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

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

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

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

list
.where(x => x % == )
.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) / ;
var currentTime = new DateTime(,,).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) / ;
var currentTime = new DateTime(,,).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) / ;
var currentTime = new DateTime().AddMilliseconds(ms).ToLocalTime();
Console.WriteLine(currentTime);
}

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