読者です 読者をやめる 読者になる 読者になる

Generics 以外への default キーワードの活用

.NET

以前書いた Strong-typed reflection (id:NyaRuRu:20070826:p2) ですが,なんか default キーワードでいいやって気がしてきました.さらに書き換え.

using System;
using System.Linq.Expressions;
using System.Reflection;

public static class Program
{
    static void Main(string[] args)
    {
        // DateTime.get_Now : () -> DateTime
        var mi1 = Reflector.Function<DateTime>.Bind(() => DateTime.Now);

        // Array.Sort<T>(T[]) : int[] -> ()
        var mi2 = Reflector.Function.Bind(() => Array.Sort(default(int[])));

        // string.EndsWith(string) : (string -> ) string -> bool
        var mi3 = Reflector.Function<bool>.Bind(() => (default(string)).EndsWith(default(string)));
    }
}

public static class Reflector
{
    static MethodInfo GetMethodInfo(this Expression expression)
    {
        var findfunc = default(Func<Expression, MethodInfo>);
        findfunc = expr =>
        {
            switch (expr.NodeType)
            {
                case ExpressionType.Lambda:
                    return findfunc((expr as LambdaExpression).Body);
                case ExpressionType.Quote:
                    return findfunc((expr as UnaryExpression).Operand);
                case ExpressionType.Call:
                    var mce = expr as MethodCallExpression;
                    return mce != null ? mce.Method : null;
                case ExpressionType.MemberAccess:
                    var me = expr as MemberExpression;
                    var pi = me.Member as PropertyInfo;
                    return pi != null ? pi.GetGetMethod(true) : null;
                default:
                    return null;
            }
        };

        return findfunc(expression);
    }
    public sealed class Function<TResult>
    {
        public static MethodInfo Bind(Expression<Func<TResult>> expr)
        {
            return expr.GetMethodInfo();
        }
    }
    public sealed class Function
    {
        public static MethodInfo Bind(Expression<Action> expr)
        {
            return expr.GetMethodInfo();
        }
    }
}

まあここのところずっと,色々なシンタックスを考えては消し,考えては消しの繰り返しなので,まだまだ変わるかもしれませんけど.
ちなみに Anonymous Types でも default が活躍できそうな.某所の nsharp 氏のコードをちょっと書き換え.

RouteTable.Routes.Add(new Route { 
    Url = "[controller]/[action]/[id]", 
    Defaults = new { action = "Index", id = default(string) },
    RouteHandler = typeof(MvcRouteHandler) 
});

他には,id:NyaRuRu:20060224:p2 で書いた再帰の件とか.

Func<int, int> func = null;
func = delegate(int i) { return i <= 0 ? 1 : i * func(i - 1); };
Console.WriteLine(func(10));

とも書けますが,

var func = default(Func<int, int>);
func = delegate(int i) { return i <= 0 ? 1 : i * func(i - 1); };
Console.WriteLine(func(10));

でも OK ですねと.
まあ完全にシンタックスレベルの話なので,嫌いな人は適当に流して下さいということで.