加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

这个C#复制对象例程如何转换为F#?

发布时间:2020-12-16 00:01:04 所属栏目:百科 来源:网络整理
导读:我认为我编写的用于复制对象属性树的代码非常实用 – F#版本是否带来了另一层次的简洁性? public static class CopyUtility{ public static void Copy(object source,object target) { ( from s in Properties(source) from t in Properties(target) where
我认为我编写的用于复制对象属性树的代码非常实用 – F#版本是否带来了另一层次的简洁性?

public static class CopyUtility
{
    public static void Copy(object source,object target)
    {
        (
            from s in Properties(source)
            from t in Properties(target)
            where Matches(s,t)
            select Action(t,target,s.GetValue(source,null))
        )
        .ToList().ForEach(c => c());
    }

    static IEnumerable<PropertyInfo> Properties(object source)
    {
        return source.GetType().GetProperties().AsEnumerable();
    }

    static bool Matches(PropertyInfo source,PropertyInfo target)
    {
        return source.Name == target.Name;
    }

    static Action Action(PropertyInfo source,object target,object value)
    {
        if (value.GetType().FullName.StartsWith("System."))
            return () => source.SetValue(target,value,null);
        else
            return () => Copy(value,source.GetValue(target,null));
    }
}

解决方法

这是转换为F#的C#复制功能:

module CopyUtility

let rec copy source target =
    let properties (x:obj) = x.GetType().GetProperties()
    query {
        for s in properties source do
        join t in properties target on (s.Name = t.Name)
        select s }
    |> Seq.iter (fun s ->
        let value = s.GetValue(source,null)
        if value.GetType().FullName.StartsWith("System.") 
        then s.SetValue(target,null)            
        else copy value (s.GetValue(target,null))
    )

轻巧的语法

F#使用轻量级语法,其中空格很重要,这减少了大括号占用的行数.我在C#代码中计算了28行,而在F#代码中计算了13行.

类型推断

F#复制功能只需要一个类型的注释.与C#一样,F#是静态类型语言,但F#的type inference不限于local variables.

嵌套函数

F#支持nested functions,允许在Copy函数的主体内定义属性函数.这也可以通过定义类型为Func< object,IEnumerable< PropertyInfo>>的lambda function来用C#完成.但它简明扼要.

查询语法

F#3的query expressions提供了类似于C#中LINQ的简洁语法.

流水线

F#pipe forward operator(|>)使函数调用能够作为连续操作链接在一起,通常不需要临时变量声明.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读