The story behind it

Source: Internet
Author: User

[Turn] The Story Behind and the story behind

Happy Lambda expressions

The story behind the last article-happy Lambda expressions (1) We analyzed Lambda expressions from a simple perspective. I understand the differences between it and the delegate and common methods, and test and compare the performance between them. Then I learned about Lambda expressions in depth through the IL code, and introduced how it works in. NET using Lambda expressions to implement some popular JavaScript patterns.

Today, let's take a look at some new methods of using Lambda expressions in. NET.

Lambda expressions

How does Lambda achieve polymorphism? We use abstract classes and virtual methods. Why should we use Lambda? See 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, and there is no virtual method, but the attribute is exposed by delegation, and then a new expression is assigned to our SomeAction In the subclass. This is the process of implementing polymorphism. Of course, the SomeAction set in the parent class has the protection level of protected, otherwise it will be easily modified by the external. However, this is not perfect. After the SomeAction of the parent class is overwritten in the subclass, we will never be able to access it, we can use base to access the original methods of the parent class. The following is how to implement this:

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 AddSomeAction to overwrite and save the original method in previusactions. In this way, both of them can exist at the same time.

We all know that subclass does not cover the static methods of the parent class, but suppose we want to implement static method override?

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 motherMessage = "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 daughterMessage = "I am the daughter";}}

Here, Lambda expressions are used as attributes and can be assigned again at any time. Of course, this is just a simple example. We do not recommend that you do this in real projects.

Method dictionary

In fact, we have already mentioned this pattern in the previous response method, but there is no such name, even a summary. The story is like this. Do you think it is not elegant when writing switch-case statements? But you don't want to go to the entire factory mode or strategy mode. How can you make your code look more advanced?

Public Action GetFinalizer (string input) {switch {case "random": return () => {/*... */}; case "dynamic": return () => {/*... */}; default: return () => {/*... */};}// --------------------- after transformation ----------------------- 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 seems to be different. But the thought is that all methods should be put in the BuildFinalizers. This kind of organization method is really unacceptable. Let's learn the plug-in development method and let it find all the methods we need.

Static Dictionary <string, Action> finalizers; // call this method in a static constructor: public static void BuildFinalizers () {finalizers = new Dictionary <string, Action> (); // obtain all types of var types = Assembly under the current running Assembly. getExecutingAssembly (). getTypes (); foreach (var type in types) {// check type. We can define the interface or abstract class if (type. isSubclassOf (typeof (MyMotherClass) {// obtain the default no-argument constructor var m = type. getConstructor (Type. emptyTypes); // call this default 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 () => {/*... */};}

To implement plug-ins, we should not only be able to load methods in this Assembly, but also to load external methods at any time or even during runtime. Please continue to look:

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.

The last question is, can we write recursive expressions? How can I write the following method using an expression?

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

  

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.