Как эта процедура копирования объекта C # перевести на F #? - PullRequest
3 голосов
/ 03 ноября 2011

Я думаю, что этот код, который я написал для копирования деревьев свойств объекта, довольно функционален - версия 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));
    }
}

1 Ответ

12 голосов
/ 11 февраля 2013

Вот функция копирования C #, переведенная в 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

F # использует синтаксис light, где пробел является значительным, что уменьшает числолиний, взятых фигурными скобками.Я насчитал 28 строк в коде C # против 13 в коде F #.

Вывод типа

Функция F # copy требует только аннотации одного типа.Как и C #, F # является языком статической типизации, однако вывод типа F # не ограничен локальными переменными .

Вложенные функции

F # поддерживает вложенных функций , что позволяет определять функцию properties в теле функции Copy.Это также можно сделать с помощью C #, определив лямбда-функцию типа Func<object,IEnumerable<PropertyInfo>>, но она значительно менее краткая.

Синтаксис запроса

F37: выражения запросов обеспечивают сжатый синтаксис, аналогичный синтаксису LINQ в C #.

Конвейер

Оператор прямого переноса F # (|>) позволяет объединять вызовы функций как последовательные операции, часто устраняя необходимость во временных объявлениях переменных.

...