快乐的Lambda表达式

快乐的Lambda表达式

澳门蒲京娱乐 1

澳门蒲京娱乐 2

  上一篇 骨子里的故事之 –
快乐的Lambda表达式(一)咱由浅入深的剖析了转Lambda表达式。知道了它们跟寄托以及常见方法的分别,并且经过测试对照他们中的属性,然后我们透过IL代码深入摸底了Lambda表达式,以及介绍了哪些在.NET中之所以Lambda表达式来促成JavaScript中大行其道的一部分模式。

  上一篇 幕后的故事之 –
快乐的Lambda表达式(一)我们是因为浅入深的分析了瞬间Lambda表达式。知道了她同嘱托以及日常方法的界别,并且经过测试对照他们中的习性,然后我们经过IL代码深入摸底了Lambda表达式,以及介绍了什么在.NET中因故Lambda表达式来促成JavaScript中大行其道的部分模式。

  今天,我们跟着来拘禁Lambda表达式在.NET中还有什么特殊的玩法。

  今天,我们跟着来拘禁Lambda表达式在.NET中还有什么样突出的玩法。

Lambda表达式玩转多态

  Lambda如何促成多态?我们为此抽象类和虚方法了,为什么还要用Lambda这个东西?且看下面的代码:

class MyBaseClass
{
    public Action SomeAction { get; protected set; }

    public MyBaseClass()
    {
        SomeAction = () =>
        {
            //Do something!
        };
    }
}

class MyInheritedClass : MyBaseClass
{
    public MyInheritedClass()
    {
        SomeAction = () => {
            //Do something different!
        };
    }
}

  我们的基类不是抽象类,也并未虚方法,但是把性能通过信托的计暴露出,然后以子类中另行为咱的SomeAction赋予一个初的表达式。这便是咱兑现多态的长河,当然父类中的SomeAction的set有protected的保护级别,不然就会见吃标随易修改了。但是及时尚未完善,父类的SomeAction在子类中给掩后,我们根本访问不交它们了,要了解真实情形是我们得经base来访问父类原来的方的。接下来就是实现之了:

class MyBaseClass
{
    public Action SomeAction { get; private set; }

    Stack<Action> previousActions;

    protected void AddSomeAction(Action newMethod)
    {
        previousActions.Push(SomeAction);
        SomeAction = newMethod;
    }

    protected void RemoveSomeAction()
    {
        if(previousActions.Count == 0)
            return;

        SomeAction = previousActions.Pop();
    }

    public MyBaseClass()
    {
        previousActions = new Stack<Action>();

        SomeAction = () => {
            //Do something!
        };
    }
}

  上面的代码中,我们透过AddSomeAction来落实覆盖的还要,将原本的方法保存于previousActions中。这样我们尽管得保障两岸同时是了。

  大家领略子类是免可知覆盖父类的静态方法的,但是如果我们怀念实现静态方法的掩盖也?

void Main()
{
    var mother = HotDaughter.Activator().Message;
    //mother = "I am the mother"
    var create = new HotDaughter();
    var daughter = HotDaughter.Activator().Message;
    //daughter = "I am the daughter"
}

class CoolMother
{
    public static Func<CoolMother> Activator { get; protected set; }

    //We are only doing this to avoid NULL references!
    static CoolMother()
    {
        Activator = () => new CoolMother();
    }

    public CoolMother()
    {
        //Message of every mother
        Message = "I am the mother";
    }

    public string Message { get; protected set; }
}

class HotDaughter : CoolMother
{
    public HotDaughter()
    {
        //Once this constructor has been "touched" we set the Activator ...
        Activator = () => new HotDaughter();
        //Message of every daughter
        Message = "I am the daughter";
    }
}

  这里要利用了以Lambda表达式作为性能,可以天天再次赋值的性状。当然就只是是一个略的演示,真实项目遭到并无建议大家这么去开。 

Lambda表达式玩转多态

  Lambda如何落实多态?我们就此抽象类和虚方法了,为什么还要用Lambda这个家伙?且看下的代码:

class MyBaseClass
{
    public Action SomeAction { get; protected set; }

    public MyBaseClass()
    {
        SomeAction = () =>
        {
            //Do something!
        };
    }
}

class MyInheritedClass : MyBaseClass
{
    public MyInheritedClass()
    {
        SomeAction = () => {
            //Do something different!
        };
    }
}

  我们的基类不是抽象类,也从没虚方法,但是将性能通过委托的方式暴露出来,然后在子类中还为我们的SomeAction赋予一个初的表达式。这虽是我们贯彻多态的历程,当然父类中之SomeAction的set有protected的保护级别,不然就是会吃表面随易修改了。但是及时还无完美,父类的SomeAction在子类中受覆盖下,我们根本访问不至它了,要理解真实情况是咱得以经过base来访问父类原来的措施的。接下来就贯彻此了:

class MyBaseClass
{
    public Action SomeAction { get; private set; }

    Stack<Action> previousActions;

    protected void AddSomeAction(Action newMethod)
    {
        previousActions.Push(SomeAction);
        SomeAction = newMethod;
    }

    protected void RemoveSomeAction()
    {
        if(previousActions.Count == 0)
            return;

        SomeAction = previousActions.Pop();
    }

    public MyBaseClass()
    {
        previousActions = new Stack<Action>();

        SomeAction = () => {
            //Do something!
        };
    }
}

  上面的代码中,我们透过AddSomeAction来兑现覆盖的而,将原本的办法保存在previousActions中。这样咱们就算好维持双方又设有了。

  大家领略子类是未能够遮盖父类的静态方法的,但是要我们纪念实现静态方法的埋也?

void Main()
{
    var mother = HotDaughter.Activator().Message;
    //mother = "I am the mother"
    var create = new HotDaughter();
    var daughter = HotDaughter.Activator().Message;
    //daughter = "I am the daughter"
}

class CoolMother
{
    public static Func<CoolMother> Activator { get; protected set; }

    //We are only doing this to avoid NULL references!
    static CoolMother()
    {
        Activator = () => new CoolMother();
    }

    public CoolMother()
    {
        //Message of every mother
        Message = "I am the mother";
    }

    public string Message { get; protected set; }
}

class HotDaughter : CoolMother
{
    public HotDaughter()
    {
        //Once this constructor has been "touched" we set the Activator ...
        Activator = () => new HotDaughter();
        //Message of every daughter
        Message = "I am the daughter";
    }
}

  这里还是以了以Lambda表达式作为性能,可以天天再次赋值的特性。当然就就是一个大概的演示,真实项目中连无建议大家这么去举行。 

办法字典

  实际上是模式我们以达成同首的归来方法未遭已提到了,只是没有如此一个名而已,就终于一个总结吧。故事是这般的,你是无是经常会面刻画及switch-case语句子之上以为不够优雅?但是你以未思去整个什么工厂模式或者政策模式,那怎么被您的代码看起高档一点呢?

public Action GetFinalizer(string input)
{
    switch
    {
        case "random":
            return () => { /* ... */ };
        case "dynamic":
            return () => { /* ... */ };
        default:
            return () => { /* ... */ };
    }
}

//-------------------变身之后-----------------------
Dictionary<string, Action> finalizers;

public void BuildFinalizers()
{
    finalizers = new Dictionary<string, Action>();
    finalizers.Add("random", () => { /* ... */ });
    finalizers.Add("dynamic", () => { /* ... */ });
} 

public Action GetFinalizer(string input)
{
    if(finalizers.ContainsKey(input))
        return finalizers[input];

    return () => { /* ... */ };
}

  好像看起是休一样了,有那一些寓意。但是同样想是所有的法都要放到那个BuildFinalizers里面,这种组织办法其实是难承受,我们来学学插件开发的艺术,让她好去找寻有我们用的方式。

static Dictionary<string, Action> finalizers;

// 在静态的构造函数用调用这个方法
public static void BuildFinalizers()
{
    finalizers = new Dictionary<string, Action>();

    // 获得当前运行程序集下所有的类型
    var types = Assembly.GetExecutingAssembly().GetTypes();

    foreach(var type in types)
    {
        // 检查类型,我们可以提前定义接口或抽象类
        if(type.IsSubclassOf(typeof(MyMotherClass)))
        {
            // 获得默认无参构造函数
            var m = type.GetConstructor(Type.EmptyTypes);

            // 调用这个默认的无参构造函数
            if(m != null)
            {
                var instance = m.Invoke(null) as MyMotherClass;
                var name = type.Name.Remove("Mother");
                var method = instance.MyMethod;
                finalizers.Add(name, method);
            }
        }
    }
} 

public Action GetFinalizer(string input)
{
    if(finalizers.ContainsKey(input))
        return finalizers[input];

    return () => { /* ... */ };
}

  如果一旦兑现插件化的话,我们不光要能加载本程序集下的点子,还要能够天天甚至运转时去加载外部的法门,请继续为生看:

internal static void BuildInitialFinalizers()
{
    finalizers = new Dictionary<string, Action>();
    LoadPlugin(Assembly.GetExecutingAssembly());
}

public static void LoadPlugin(Assembly assembly)
{
    var types = assembly.GetTypes();
    foreach(var type in types)
    {
        if(type.IsSubclassOf(typeof(MyMotherClass)))
        {
            var m = type.GetConstructor(Type.EmptyTypes);

            if(m != null)
            {
                var instance = m.Invoke(null) as MyMotherClass;
                var name = type.Name.Remove("Mother");
                var method = instance.MyMethod;
                finalizers.Add(name, method);
            }
        }
    }
} 

  现在,我们不怕可用这个法子,给她指定程序集去加载我们得之事物了。

  最后留给大家一个题目,我们会写递归表达式么?下面的点子而用表达式如何勾勒为?

int factorial(int n)
{
    if(n == 0)
        return 1;
    else
        return n * factorial(n - 1);
}

  

计字典

  实际上这模式我们于上同一首的回去方法被曾经说到了,只是没如此一个名而已,就到底一个总结吧。故事是这般的,你是休是时会面写到switch-case语句子之时段觉得不够优雅?但是你而不思量去整个什么工厂模式或者政策模式,那如何被你的代码看起高档一点乎?

public Action GetFinalizer(string input)
{
    switch
    {
        case "random":
            return () => { /* ... */ };
        case "dynamic":
            return () => { /* ... */ };
        default:
            return () => { /* ... */ };
    }
}

//-------------------变身之后-----------------------
Dictionary<string, Action> finalizers;

public void BuildFinalizers()
{
    finalizers = new Dictionary<string, Action>();
    finalizers.Add("random", () => { /* ... */ });
    finalizers.Add("dynamic", () => { /* ... */ });
} 

public Action GetFinalizer(string input)
{
    if(finalizers.ContainsKey(input))
        return finalizers[input];

    return () => { /* ... */ };
}

  好像看起是不同等了,有那么一些寓意。但是同想是兼具的方式都如放那个BuildFinalizers里面,这种组织办法其实是为难承受,我们来上学插件开发的办法,让它们和谐去摸索有我们需要的主意。

static Dictionary<string, Action> finalizers;

// 在静态的构造函数用调用这个方法
public static void BuildFinalizers()
{
    finalizers = new Dictionary<string, Action>();

    // 获得当前运行程序集下所有的类型
    var types = Assembly.GetExecutingAssembly().GetTypes();

    foreach(var type in types)
    {
        // 检查类型,我们可以提前定义接口或抽象类
        if(type.IsSubclassOf(typeof(MyMotherClass)))
        {
            // 获得默认无参构造函数
            var m = type.GetConstructor(Type.EmptyTypes);

            // 调用这个默认的无参构造函数
            if(m != null)
            {
                var instance = m.Invoke(null) as MyMotherClass;
                var name = type.Name.Remove("Mother");
                var method = instance.MyMethod;
                finalizers.Add(name, method);
            }
        }
    }
} 

public Action GetFinalizer(string input)
{
    if(finalizers.ContainsKey(input))
        return finalizers[input];

    return () => { /* ... */ };
}

  如果假定贯彻插件化的话,我们不仅要力所能及加载本程序集下的法,还要会时时甚至运转时失去加载外部的计,请继续于下看:

internal static void BuildInitialFinalizers()
{
    finalizers = new Dictionary<string, Action>();
    LoadPlugin(Assembly.GetExecutingAssembly());
}

public static void LoadPlugin(Assembly assembly)
{
    var types = assembly.GetTypes();
    foreach(var type in types)
    {
        if(type.IsSubclassOf(typeof(MyMotherClass)))
        {
            var m = type.GetConstructor(Type.EmptyTypes);

            if(m != null)
            {
                var instance = m.Invoke(null) as MyMotherClass;
                var name = type.Name.Remove("Mother");
                var method = instance.MyMethod;
                finalizers.Add(name, method);
            }
        }
    }
} 

  现在,我们不怕好据此这主意,给她指定程序集去加载我们用的事物了。

  最后留给大家一个问题,我们会写递归表达式么?下面的点子要因此表达式如何勾勒为?

int factorial(int n)
{
    if(n == 0)
        return 1;
    else
        return n * factorial(n - 1);
}