C #3.0 Written by Allen Lee in my eyes

Source: Internet
Author: User

C #3.0 in my eyes

 

Written by Allen Lee

 

Origin

Every time a new technology is released, we can always feel two completely different emotions: fear and resistance, and with such emotions, "C #2.0 is quite useful, why is it so complicated in C #3.0? "Or" I am still using C #1.0? "And other words; the other is excitement and hug. With such emotions, there are also such things:" It turns out that this problem can be so simple in C #3.0! .

Recently, I gave a series of lectures on LINQ in my company. When I prepared a presentation for C #3.0 new features, I suddenly came up with the idea of writing this article. There is no right or wrong distinction between the characteristics of a language and itself. Whether or not to accept it is a matter of sensibility, that is, whether you like this way of doing things, I am not trying to persuade anyone to accept C #3.0 and LINQ. I just want to share my feelings with you when I write this article.

One time I watched a training video on Expression Blend, which gave me a very deep impression:

I know how it works because I know why it works.

If you savor this sentence, you will feel the information it wants to convey: understanding why this function is needed can help you better understand how to use this function, this is exactly the expression I want to use in this article.

 

How do you create attributes?

If you use C # For a long time, I believe you will not be unfamiliar with the attribute. Generally, attributes are a simple packaging of private fields, like this:

Code 1

One advantage of using properties rather than directly publishing private fields is that adding additional logic to the property accessor set accessors does not cause trouble for client code, for example, you want to perform some additional checks when setting the title. But if you just wrap it up, like the code above, you will find that you actually write a lot of code that can be omitted. Since the Title attribute corresponds to the m_Title private field, the retrieved accessors certainly return the m_Title value, and the Set accessors certainly set the value to m_Title. Furthermore, if you only access this data through the Title attribute, then the m_Title private field will become insignificant. So, why not give it to the compiler? At this time, the automatic attributes of C #3.0 can be used:

Code 2

The compiler will create a private field for you, and let the accessors get and set the accessors to point to this private field. Of course, if necessary, for example, you can expand the accessors and accessors at any time when you want to add additional logic to the accessors or set the accessors.

 

How do you initialize an object?

Now, suppose we have a class like this:

Code 3

How do you initialize it? One way is to use the Book's default constructor to create an object instance and assign values to each attribute:

Code 4

Another way is to use the C #3.0 object initializer:

Code 5

At first glance, the C #3.0 practice does not seem to have any sense of superiority. Now, please take a closer look at how many ";"? Code 4 has five ";", which means that it uses five statements for initialization; Code 5 has only one ";", which means that it only uses one statement for initialization. From the lexical perspective, if I can only accept one expression at the moment, then code 4 will not help. A work und is to provide constructors with parameters for the Book class, but this method also has drawbacks. Users may only want to provide data for some attributes during initialization, however, we cannot accurately predict the combinations of attributes that users will provide. Therefore, we may need to provide users with enough constructors to overload them. Well, it's boring and redundant. Another work und is to provide constructors that accept the most parameters. If a user passes null for a parameter, the corresponding attribute is ignored. This method is close to code 5, the difference is that if you have many attributes and users only care about a few, you may have to enter a lot of null values.

Now, if you want to instantiate a set of Book objects and store them in a set, what do you do? The following is a common practice:

Code 6

If you use the C #3.0 object initialization tool and set initialization tool, you can simplify the code:

Code 7

Each element in the set is separated by "," and used with the object initiator. The structure of the entire set is clear. Dictionary Initialization is also simple:

Code 8

Speaking of this, I believe you can also feel that C # seems to be being expressionized, but now it can be described in a single expression that requires a lot of statements in the past, this concept is also infiltrated into the entire C #3.0 atmosphere.

 

How did you outsource the computing logic?

Suppose that I have a set of instance objects of books and you want to sort them, how do you tell them that you want to sort them by price?

Code 9

In C #1.0, We need to specifically provide it with an independent method:

Code 10

Then, input the required instance to the Sort () method:

Code 11

This can be further simplified in C #2.0 as follows:

Code 12

If you use the anonymous method of C #2.0, you can save a lot of unnecessary code:

Code 13

In addition, using the anonymous method, the Sort () method and the logic you want it to use to compare two Book instance objects can be placed in the same place; instead, using an independent naming method, methods that contain this logic may be moved to other places due to code sorting. In this way, when you see Code 12, you have to spend some energy looking for the Compare () method to understand its internal implementation. Of course, you can argue that we can develop a code specification so that the Compare () method must be kept below the Sort () method. Yes, you can, but if this logic does not need to be reused, then using the anonymous method still has obvious advantages. If this logic needs to be reused, the anonymous method will be powerless.

Now let's take a look at code 13. Have you found that the expression of the anonymous method is not concise enough? We know that the books set contains only the instance objects of the Book, so the type of the two parameters passed by the Sort () method must be Book, and the result expected by the Sort () method is x. price. compareTo (y. price) the operation result of this expression. The words delegate and return can be said to be completely redundant here. Why do we not express them directly:

Code 14

This is the Lambda expression syntax introduced by C #3.0. I have met some people who often emphasize simplicity as much as possible, but if things suddenly become much simpler than they expected, they will begin to feel uncomfortable or even refuse to accept such simplicity, in fact, even if the development direction of things is the same as that of your forward direction, if the development speed is greatly higher than yours, it may still lead to your fear of getting out of control. I hope that the Lambda expression syntax won't make you feel too uncomfortable. Of course, I hope you will like it more.

Lambda expressions can be understood very easily, that is, "=>" parameters on the left participate in expression operations on the right, and the operation results will be returned, which is a bit like a compound reaction, that is, two or more substances (parameters on the left) generate a new substance (calculation result of the expression on the right). The difference is that Lambda does not receive any parameters, or no results are returned.

"=>" In addition to expressions, statements can also be placed on the right side, as shown in the following code:

Code 15

We call it a Lambda Statement (Lambda Statement). You may have discovered that it does not need to write delegate keywords or parameter types compared with anonymous methods.

 

How do you extend related functions for objects?

I keep wondering why the String class does not provide a Reverse () method to flip the String? I guess it's probably because this operation doesn't really mean anything unless you're playing a text game. It is not difficult to implement the Reverse () method. The following is one of the methods:

Code 16

The usage is also very simple:

Code 17

You can even put the Reverse () method in a static class, such as Utils, so that code 17 can be changed:

Code 18

Before C #3.0, you can only go here at most, and to C #3.0, you can also use the extension method to make further adjustments to it so that Code 18 becomes:

Code 19

It looks like the Reverse () method belongs to a String, and all you need to do is add the "this" keyword before the target parameter of the Reverse () method:

Code 20

We know that the underlying world of the computer does not know what object orientation is. The instance methods we define in the object contain a hidden parameter, which is a pointer to the current object instance, the Extension Method of C #3.0 imitates this method in form, but because the extension method is not essentially a class related to it, you cannot define private members inside the extension class in the extension method.

As discussed above, you may think that Code 19 has no significant advantage over Code 18. Why do you need to extend the method? Suppose we have a bunch of books on hand, and I want to find the cheapest book in LINQ, which can be written like this using the standard query operator:

Code 21

We know that Where (), OrderBy (), and First () are extension methods. If C #3.0 does not support extension methods, code 21 has to be written as follows:

Code 22

The readability of code 21 is obviously higher than that of code 22 and more natural. At this time, we only use three standard query operators. You can imagine, what is the scenario of expressing more complex queries without the support of extension methods?

 

How do you express what you want?

Now, assume that I want to find the cheapest LINQ book and use the C #2.0 syntax, I may need:

Code 23

Although Array. indexOf () method, List <T>. the Sort () method and anonymous functions simplify the code, but it still cannot cover up the fact that I am telling how to get what I want, this is also the core idea of Imperative Programming (Imperative Programming.

If you use the C #3.0 syntax, the situation will be quite different:

Code 24

Here, you express what you want, rather than the specific steps to get these things. This is the core idea of Declarative Programming. The benefits of doing so are obvious, your needs can be re-resolved and executed, and the underlying implementation can be optimized if necessary, but since you do not care about and involve specific implementations, so those optimizations won't cause you to modify the code.

Imperative programming is like process management. You need to go deep into the execution details and then implement control over the execution of the entire process. Declarative Programming is like Target Management (MBO), and you set goals, and allocate the task for execution. Code 23 gives people the feeling that the entire execution process is very clear, you can modify or tune any step; code 24 gives people the feeling that you can't do anything except say what you want, which may be unacceptable for those Process Management owners, they feel anxious because they have lost control of things and cannot establish a sense of security. Someone once complained to me: If you use LINQ, you can only force yourself to believe that its implementation is good. Think about it. If your company contracts the canteen business to a catering company, can your company intervene in how others recruit chefs, how to buy food, and how to cook? Choosing LINQ means that you are willing to give the execution details to others for processing, so as to break away from these details. If you cannot put down the control on these details at all, then LINQ may not be suitable for you.

It is hard to say that these two programming methods are superior and inferior, because in some cases, managers who are good at process management can indeed make the situation develop in the correct direction; in other cases, goal Management provides sufficient freedom for implementers to encourage them to think positively. The management circle seems to have never stopped over the arguments about superior and inferior process management and target management. What's more, the programming circle is about imperative programming and Declarative Programming, I personally prefer to think of this as finding a style that is more suitable for you than blindly listening to others' opinions. Whether the language plays a positive or negative role depends largely on the user. We should use the favorable aspect of the language to assist our work, instead of hurting yourself and others with its harmful side.

Return to code 24, which returns all the information of a qualified book to me. What if I only need the name of the book and the name of the author? We know that in the object-oriented world, information is stored in objects, so we have to go to an embarrassing situation, that is, we need to create a temporary class for this:

Code 25

The nightmare officially started. What if I need the title and price? What if I need a title, author, and price ?...... (You can complete this list by yourself.) At this time, it is the turn of C #3.0's anonymous type and implicit type variables:

Code 26

Because the anonymous type is automatically generated by the compiler, but it does not have a name when you write code, you cannot use this type to declare this variable, in this case, the "var" keyword is used. This is the initial purpose of the "var" keyword, but thanks to the type inference system, we can also use the "var" keyword to declare any local variable, as long as we initialize it while declaring it, otherwise, the compiler cannot infer. Someone once asked me: What if I want to return the wanted7 code in code 26? We know that the return value of a method needs to clearly define the type. When we write code 26, the compiler has not named the anonymous type in the query expression. If you really want to return it, you can only set the type of the return value of the method to IEnumerable <object>, because we can only determine that the anonymous type is the descendant of the object, but in this way, the client code is not too good, because it is not an alternative to accessing your object through reflection. If you really want to return it, it means that you need to share this object with the client code. The proper way to do this is to use the naming type. In addition, the "book. title "is" Title = book. the abbreviation of Title. If you omit "Title =", the compiler assumes that you want the name and Book of this attribute of the anonymous type. the Title is the same.

Another interesting thing about the anonymous type is that it used to be mutable but then immutable. In Immutable is, the new Anonymous Type explains this change. We know that in the object-oriented world, objects are encapsulated and maintained, and the state of objects is affected by the side effects of calling object methods, immutable is the core feature of Functional Programming (Functional Programming). You may have noticed that C #3.0 has introduced a lot of Functional Programming stuff, functional programming languages also seem to have to get started. What exactly does this mean?

 

Where is the road ahead?

Whether you admit it or not, C #3.0 is easier to express than the previous version, but to get this simple, you must arm your head with a lot of things first, this reminds me of a sentence I saw in a book:

Simplicity is supported by complexity.

The mutual penetration between different languages is no longer a novelty. The introduction of other language functions can sometimes be seen as a strategic intrusion into the competitor's market, to some extent, this is a bit like mixed operation in the financial industry. What will happen to the next C # version? Maybe you are excited about this problem. You even want to let C # Team look at your creativity now. Maybe this problem makes you sad, and you are afraid that you will not be able to adapt to the next wave of changes, this is because changes may lead to instability, instability may lead to runaway, and runaway may lead to anxiety. In any case, it cannot be avoided. Maybe now let's take a look at What Is the Future of C # Anyways in Matthew Podwysocki. Is there any inspiration ......

 

Appendix: if you are interested in viewing my presentation, click here to download it.

 

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.