The story behind-happy lambda expression (ii)

Source: Internet
Author: User
Tags case statement
The story behind the previous article – The Happy Lambda expression (i) we analyzed the lambda expression from the very first. Knowing the difference between it and the delegate as well as the common method, and comparing the performance between them by testing, we learned more about lambda expressions through IL code and how to do it in. NET uses lambda expressions to implement some of the patterns prevalent in JavaScript.

Today, let's take a look at some of the new ways lambda expressions are available in. Net.

Lambda expression topsy-polymorphism

How does lambda implement polymorphism? We use abstract classes and virtual methods, why do we use lambda this thing? And look at the following code:

Class mybaseclass{public    Action someaction {get; protected set;}     Public MyBaseClass ()    {        someaction = () =        {            //do something!        };}    } class Myinheritedclass: mybaseclass{public    Myinheritedclass ()    {        someaction = () = {            //do something different!        };    }}

Our base class is not an abstract class, there is no virtual method, but exposes the property through a delegate, and then re-assigns a new expression to our someaction in the subclass. This is the process of implementing polymorphism, of course, the someaction set in the parent class has a protected level of protection, otherwise it will be modified externally with ease. But this is not perfect, the parent class someaction is overwritten in the subclass, we can not access it completely, to know that the real situation is that we could access the original method of the parent class through base. This is the next step.

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!        };}    }

In the above code, we use the addsomeaction to implement the overlay and save the original method in the Previousactions. So we can keep the two together.

It is known that subclasses cannot overwrite the static methods of the parent class, but suppose we want to implement static method overrides?

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 se T }//we is 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 have been "touched" we set th E-Activator        ... Activator = () = new Hotdaughter ();        Message of every daughter        message = "I am the Daughter";    }}

It also takes advantage of the ability to reassign a lambda expression as an attribute at any time. Of course, this is just a simple example, and the real project doesn't suggest that you do it.

Method Dictionary

In fact, we've talked about this pattern in the return method of the previous article, but there's no such a name, even a summary. The story is, do you often write to the switch-case statement when you feel not elegant? But you don't want to go to the whole plant or strategy model, so how do you make your code look a bit more advanced?

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 () = {/* ... */};}

It looks like it's not the same, it tastes a little bit. But one thought is that all the methods must be put into that buildfinalizers, this kind of organization method is very difficult to accept, we learn to learn the way of plug-in development, let it find all the methods we need.

static dictionary<string, action> finalizers;//In static constructors call this method public     static void Buildfinalizers () {finalizers = new dictionary<string, action> (); Get all the types under the currently running assembly var types = assembly.getexecutingassembly ().     GetTypes (); foreach (var type in types) {//Check the type, we can define the interface in advance or the abstract class if (type. IsSubclassOf (typeof (Mymotherclass))) {//Get the default parameterless constructor var m = type.             GetConstructor (type.emptytypes);                Call this default parameterless constructor 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 () = {/* ... */};} 

If we want to implement plug-ins, we should not only be able to load the method under this assembly, but also to be able to load the external method at any time even when running, please continue to look down:

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);}}}}    

Now, we can use this method to specify the assembly to load what we need.

Finally, let us have a question, can we write a recursive expression? How do I write the following method if I use an expression?

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

The above is the story behind-happy lambda expression (ii) of the content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.