分类目录归档:C#

几个版本的Y组合子

C#版

static Func<T, TResult> Fix<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> f)
{
    return x => f(Fix(f))(x);
}

static Func<T1, T2, TResult> Fix<T1, T2, TResult>(Func<Func<T1, T2, TResult>, Func<T1, T2, TResult>> f)
{
    return (x, y) => f(Fix(f))(x, y);
}

JavaScript版

var Y = function (F) {
 return (function (x) {
  return F(function (y) { return (x(x))(y);});
  })
		(function (x) {
  return F(function (y) { return (x(x))(y);});
  }) ;
} ;

应用

// var g = λf.λn.(n <= 1 ? 1 : n * f(n - 1))
var g = function(f) {
    return function(n) {
        if(n <= 1) {
            return 1
        } else {
            return n*f(n-1);
        }
    }
}

alert(Y(g)(5))

尾递归遍历节点树

用尾递归的形式找到节点的所有父节点,并且按照父节点到子节点的顺序排列。记录一下:

节点类:

public class Node
{
    public string Name { get; set; }
    public Node Parent { get; set; }
}

遍历:

private void traverse_node(Node node, Action<Node> con)
{
    if (node == null)
    {
        con(node);
        return;
    }
    traverse_node(node.Parent, (parent) =>
    {
        PlaceHolder1.Controls.Add(
            new Literal() { Text = node.Name + "<br />" });
        con(parent);
    });

}

调用:

protected override void OnPreRender(EventArgs e)
{
    base.OnPreRender(e);

    Node node1 = new Node() { Name = "Node1" };
    Node node2 = new Node() { Name = "Node2" };
    Node node3 = new Node() { Name = "Node3" };
    Node node4 = new Node() { Name = "Node4" };
    Node node5 = new Node() { Name = "Node5" };

    node5.Parent = node4;
    node4.Parent = node3;
    node3.Parent = node2;
    node2.Parent = node1;

    traverse_node(node5, (n) => { });
}

输出的是:

Node1<br />
Node2<br />
Node3<br />
Node4<br />
Node5<br />

获取匿名对象的属性

namespace System.Extension.Dynamic
{
    public static class Dynamic
    {
        private static Dictionary<PropertyInfo, object> propertyGetters = new Dictionary<PropertyInfo, object>();
        public static object Property(this object instance, string name)
        {
            var instanceType = instance.GetType();
            var propertyInfo = instanceType.GetProperty(name);
            if (propertyInfo == null) throw new InvalidOperationException();
            if (!propertyInfo.CanRead) throw new InvalidOperationException();

            object compiled;
            if (!propertyGetters.TryGetValue(propertyInfo, out compiled))
            {
                var parameter = Expression.Parameter(typeof(object), "obj");
                var convertParameter = Expression.Convert(parameter, instance.GetType());
                var property = Expression.Property(convertParameter, propertyInfo);
                var convertReturnValue = Expression.Convert(property, typeof(object));
                var lambda = Expression.Lambda(convertReturnValue, parameter);
                compiled = lambda.Compile();
                propertyGetters.Add(propertyInfo, compiled);
            }
            return ((Func<object, object>)compiled)(instance);
        }
    }
}