C # Study Notes 8,

Source: Internet
Author: User

C # Study Notes 8,

1.Generic constraints:

(1) interface constraints;

(2) The base class constraint must be placed first (if there are multiple constraints );

(3) struct/class constraints;

(4) Constraints on multiple parameter types. Each type parameter must use the where keyword;

(5) constructor constraints, such as new ();

(6) constraints can be inherited by the derived class, but they must be explicitly specified in the derived class;

(7) constraints of generic methods are the same as those of generic classes;

2.Covariance and inversion: in a generic type, assign a more specific type to a more general type, that is, covariance. Assign a generalized type to a more specific type, that is, the inverter.

Covariant: in C #4.0, The out type parameter modifier allows covariant. The out type parameter, this type of parameter can only be used for member return and attribute value methods. It is never used for parameter input or attribute value assignment methods.

Invert: The in type parameter modifier can be used in C #4.0. This type parameter can be used only for member input (input parameter) and attribute setting method.

For example, if the Contact class is inherited from PdaItem and the generic interface (IConvertible <in T1, out T2>) is set to covariant and invert, you can successfully convert from an IConvertible <PdaItem, Contact> to an IConvertible <Contact, PdaItem>.

To sum up, we recommend that you perform a forward-backward Association.

3.The array itself supports coordination and inversion, such as PdaItem [] pdaItems = new Contact [] {}, Contact [] pdaItems = (Contact) new PdaItem [] {}.

4.Delegation Overview: Experienced C and C ++ programmers have used method pointers to pass executable steps (methods) as parameters to another method. C # Use delegation to provide the same functions. It encapsulates methods as objects and allows you to bind a method call at runtime. You can view the DelegateSample class code.

5.Definition of delegation: C # defines all delegates as indirectly derived from System. Delegate. Its Inheritance level is Object-> Delegate-> MulticastDelegate-> Custom Delegate. Of course, we use the key delegate statement. The lece code generated after compilation automatically inherits the above structure, so we cannot manually explicitly inherit the delegate. In delegate instantiation, you can create manually from the C@2.0 without using new, directly assigning the same signature method, the compiler will automatically deduce according to the delegate during the compilation process, automatically add new creation and pass the method name as the delegate parameter,

6.System Custom delegate: In. net3.5 (C #3.0) adds the Action and Func generic delegation. The former is a delegate with no return value, and the latter is a delegate with a return value. in Net4.0 (C #4.0), The in (inverter)/out (covariant) function is added to these generic delegation. The definitions of these delegates omit the case where we manually customize the delegates, because these generic delegates cover all the usage situations we may encounter. (Unless you want to define a delegate name with special meanings ).

7.You can view the code of the DelegateSample. CovariantAndContravariant () method for the variability of delegate type parameters.

8.Lambda expressions: Lambda expressions are simple expressions of anonymous functions. Lambda expressions include statements Lambda and expressions Lambda. The former can contain statement blocks of multiple statements (generally only two or three statements are used ), the latter has only one expression.

9.Precautions for using Lambda expressions:

(1) Lambda expressions are non-typed. Only when a value is assigned to a delegate, a Lambda expression is represented as a type, that is, the delegate of the signature of the method.

(2) Because Lambda expressions are non-typed, they cannot be assigned to implicit local variables.

(3) If the destination is outside the Lambda expression, C # cannot use Jump statements (break, goto, AND continue) in anonymous functions. Similarly, you cannot jump from outside the Lambda expression to inside the Lambda expression.

(4) For variables introduced within a Lambda expression, the scope of the variables is limited to the Lambda expression body.

(5) The program execution process analysis mechanism of the compiler cannot detect local variables initialized within the Lambda expression.

For the code example of the preceding precautions, you can view the DelegateSample. NoticeMatter () method.

10.Lambda expressions are not inherent in CLR, and their implementations are generated by the C # compiler during compilation, the compiler automatically generates a Lambda expression as an internal method (static or instance method) of the current class. The method name is automatically processed by the compiler (which generally contains the description of anonymous and other words ).

11.When an external local variable is used in an anonymous function, the compiler will generate these external variables into public fields of the nested class (sealed closure) of the current class, its nested class contains public fields and the corresponding anonymous name method, so these local variables become nested members, and their life cycle is extended. By checking ILdasm (intermediate language decompilation, you can view the compiled intermediate language of the class library, which is included in the VS tool ). You can also view the DelegateSample. AscendingAndTimeOfCompiler () and _ LocalDisplayClass_00001 Nested classes.

12.Expression Tree: "interpretation" is an important motivation for C # To introduce the expression tree concept. If a Lambda expression represents data related to the expression, instead of compiled code (anonymous functions and delegation), this Lambda expression is the "Expression Tree ". Because the expression tree represents data rather than compiled code, you can convert the data into an alternative format.

For example, you can convert the expression data to the SQL code executed in the database. For example, the IQueryable Interface contains the expression tree type, query supplier, and query return types. You only need to implement this interface to query specific data sources, contains commands that require custom parsing Expression Tree. All Expression tree types (such as ParameterExpression, BinaryExpression, and MethodCallExpression) are inherited from Expression.

13.Comparison between Lambda expressions and Expression Tree: both the Lambda expressions used for delegation and the Lambda expressions used for Expression Tree are compiled. In both cases, the syntax of the expression is compiled with complete semantic analysis. However, the difference between the two is that Lambda Expressions are repeatedly compiled into a delegate in the pencil, and the Expression tree is compiled into a data structure of the System. Linq. Expressions. Expression type. You can view the AnalysisExpression code and the data Output by the Output () method.

14.An Expression tree consists of zero or more other Expression trees. The contained Expression Tree is stored in the Body attribute of the Expression. In general, statements Lambda and expression Lambda can be used interchangeably. However, you can only use the expression Lambda syntax to represent the expression tree instead of converting statements Lambda into an "Expression Tree ".

Public class DelegateSample {// Bubble sorting. The basic sorting process is public static void BubbleSort <TSource> (TSource [] items, Func <TSource, TSource, bool> predicate) where TSource: IComparable <TSource>, IEquatable <TSource> {if (items = null | items. length <2) {return;} TSource tempItem;/* first algorithm, for (int I = 0; I <items. length; I ++) {for (int j = I; j <items. length; j ++) {if (predicate (items [I], items [j]) {t EmpItem = items [I]; items [I] = items [j]; items [j] = tempItem ;}}* // The second algorithm, compare for (int I = items one by one. length-1; I> = 0; I --) {for (int j = 1; j <= I; j ++) {if (predicate (items [j-1], items [j]) {tempItem = items [j-1]; items [j-1] = items [j]; items [j] = tempItem ;}}} public static void Ascending () {int [] items = new int [] {3, 2, 1, 4, 6, 5}; Console. writeLine ("before ascending order"); foreach (var it Em in items) {Console. write ("{0} \ t", item);} BubbleSort (items, (first, second) => first> second); Console. writeLine ("\ n ASCENDING"); foreach (var item in items) {Console. write ("{0} \ t", item) ;}} public static void Descending () {int [] items = new int [] {3, 2, 1, 4, 6, 5}; Console. writeLine ("before descending order"); foreach (var item in items) {Console. write ("{0} \ t", item);} BubbleSort (items, (first, second) => fi Rst <second); Console. writeLine ("\ n after descending order"); foreach (var item in items) {Console. write ("{0} \ t", item) ;}// sort by letter public static void AlphabeticalGreaterThan () {int [] items = new int [] {1, 12, 13, 5, 4, 6}; Console. writeLine ("Before sorting"); foreach (var item in items) {Console. write ("{0} \ t", item);} BubbleSort (items, (first, second) =>{ int comparison = first. toString (). compareTo (second. toString ()); Return comparison> 0;}); Console. writeLine ("\ n sorted"); foreach (var item in items) {Console. write ("{0} \ t", item) ;}// co-variant of the Delegate and public static void CovariantAndContravariant () {// inverter Action <object> broadAction = delegate (object data) {Console. writeLine (data) ;}; Action <string> narrowAction = broadAction; // covariant Func <string> narrowFunction = () => Console. readLine (); Func <object> broadFunction = NarrowFunction; // covariant and invert Func <object, string> func1 = (data) => data. toString (); Func <string, object> func2 = func1;} // Lambda expression considerations public static void NoticeMatter () {// error: control cannot leave the body of the Lambda expression. /* String [] args; Func <string> expression; switch (args [0]) {case "/File": expression = () => {if (! File. exists (args [1]) {break ;}//... return args [1] ;}; //...} * /// local variables cannot be initialized within the Lambda expression. /* Int number; Func <string, bool> expression = text => int. tryParse (text, out number); if (expression ("1") {// error: Use the unassigned local variable Console. writeLine (number);} int number: Func <int, bool> isFortyTwo = x => 42 = (number = x); if (isFortyTwo (42 )) {// error: Use the unassigned local variable Console. writeLine (number);} * // ascending order, and record the number of comparisons. Before compilation, public static void AscendingAndTime () {int comparisonCount = 0; int [] items = new int [] {3, 2, 1, 4, 6, 5}; Console. writeLine ("before ascending order"); foreach (var item in items) {Console. write ("{0} \ t", item) ;}bubblesort (items, (first, second) =>{ comparisonCount ++; return first> second ;}); Console. writeLine ("\ n ASCENDING"); foreach (var item in items) {Console. write ("{0} \ t", item);} Console. writeLine ("\ n comparison times {0}", comparisonCount);} // sort and record the comparison times. After compilation, the public static void AscendingAndTimeOfCompile R () {_ LocalDisplayClass_00001 locals = new _ LocalDisplayClass_00001 (); locals. comparisonCount = 0; int [] items = new int [] {3, 2, 1, 4, 6, 5}; Console. writeLine ("before ascending order"); foreach (var item in items) {Console. write ("{0} \ t", item);} BubbleSort (items, locals. _ AnonymousMethod_000000); Console. writeLine ("\ n ASCENDING"); foreach (var item in items) {Console. write ("{0} \ t", item);} Console. writeLine ("\ n comparison times Count {0} ", locals. comparisonCount);} private sealed class _ LocalDisplayClass_00001 {public int comparisonCount; public bool _ AnonymousMethod_000000 (int first, int second) {comparisonCount ++; return first> second ;}}} public class AnalysisExpression {// data structure of the Output Expression Tree public void Output () {expression <Func <int, int, bool> Expression = (x, y) => x> y; Console. writeLine ("------------ {0 }------------", Expression); PrintNode (expression. body, 0); Console. writeLine ("\ n"); expression = (x, y) => x * y> x + y; Console. writeLine ("------------ {0} ------------", expression); PrintNode (expression. body, 0); Console. writeLine ("\ n");} // print Expression Tree node. The General expression Tree is private void PrintNode (expression Expression, int indent) {if (expression is BinaryExpression) {PrintNode (expression as BinaryExpression, indent);} else {PrintSingle (expression, indent) ;}// print expression Tree node, Binary expression Tree private void PrintNode (BinaryExpression expression, int indent) {// expression Tree is a data set, by traversing the data, you can convert the data into another format. The data is directly converted into the corresponding text. However, the developer decides how to interpret the data. PrintNode (expression. left, indent + 1); PrintSingle (expression, indent); PrintNode (expression. right, indent + 1);} // print the content of a single Expression Tree node private void PrintSingle (expression Expression, int indent) {Console. writeLine ("{0," + indent * 5 + "} {1}", "", NodeToString (expression ));} // convert the node to the private string NodeToString (Expression expression) {string content; switch (expression. nodeType) {case ExpressionType. multiply: content = "*"; break; case ExpressionType. add: content = "+"; break; case ExpressionType. divide: content = "/"; break; case ExpressionType. subtract: content = "-"; break; case ExpressionType. greaterThan: content = ">"; break; case ExpressionType. lessThan: content = "<"; break; default: content = string. format ("{0} ({1})", expression, expression. nodeType); break;} return content ;}}
View Code

--------------------- The above content is organized according to "C # the third edition of this topic ".

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.