문제

I think this code I wrote to copy object property trees is pretty functional - does the F# version bring another level of succinctness?

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));
    }
}
도움이 되었습니까?

해결책

Here's the C# copy function translated to F#:

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, value, null)            
        else copy value (s.GetValue(target,null))
    )

Light syntax

F# uses a light syntax where white space is significant, which reduces the number of lines taken by curly braces. I counted 28 lines in the C# code versus 13 in the F# code.

Type inference

The F# copy function requires only a single type annotation. Like C#, F# is a statically typed language, however F#'s type inference is not limited to local variables.

Nested functions

F# supports nested functions allowing the properties function to be defined within the body of the Copy function. This could be also be done with C# by defining a lambda function of type Func<object,IEnumerable<PropertyInfo>> but it is considerably less succinct.

Query syntax

F# 3's query expressions provide a succinct syntax similar to LINQ in C#.

Pipelining

The F# pipe forward operator (|>) enables function calls to be chained together as successive operations, often removing the need for temporary variable declarations.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top