C #2.0 Language Features
General generics
This makes it powerful to obtain type parameters for classes or methods.
Delegate delegates
Classes that can encapsulate one or more methods can be understood as method interfaces.
Delegate void SimpleDelegate ();
Delegate int ReturnValueDelegate ();
Delegate void TwoParamsDelegate (string name, int age );
// Delegate instantiation (C # 1.x)
Public class DemoDelegate
{
Void MethodA (){... }
Int MethodB (){... }
Void MethodC (string x, int y ){... }
Void CreateInstance ()
{
SimpleDelegate a = new SimpleDelegate (MethodA );
ReturnValueDelegate B = new ReturnValueDelegate (MethodB );
TwoParamsDelegate c = new TwoParamsDelegate (MethodC );
}
}
// Delegate instantiation (C #2.0)
Public class DemoDelegate
{
Void MethodA (){... }
Int MethodB (){... }
Void MethodC (string x, int y ){... }
Void CreateInstance ()
{
SimpleDelegate a = MethodA;
ReturnValueDelegate B = MethodB;
TwoParamsDelegate c = MethodC;
}
}
Anonymous method anonymous methods
Allows us to define code blocks that can be accepted by the delegate object. This function saves us an additional step for passing a small code block to a delegate when creating a delegate.
Delegate void SimpleDelegate ();
Public class DemoDelegate
{
Void Repeat10Times (SimpleDelegate someWork)
{
For (int I = 0; I <10; I ++) someWork ();
}
Void Run2 (){
Int counter = 0;
This. repeat10times (delegate {
Console. writeline ("C # chapter ");
Counter ++;
});
Console. WriteLine (counter );
}
}
If you do not use the anonymous method, you must
Public class Writer {
Public string Text;
Public int Counter;
Public void Dump (){
Console. WriteLine (Text );
Counter ++;
}
}
Public class DemoDelegate
{
Void Repeat10Times (SimpleDelegate someWork)
{
For (int I = 0; I <10; I ++) someWork ();
}
Void Run1 ()
{
// The SimpleDelegate delegate method is implemented in the Writer class.
Writer writer = new Writer ();
Writer. Text = "C # chapter ";
This. Repeat10Times (writer. Dump );
Console. writeline (writer. Counter );
}
}
Iterator and enumerators and Yield
An iterator is a method, get accessor or operator that allows developers to support foreach iteration in classes or structures without implementing the entire ienumerator interface.
Iterator features:
An iterator is a piece of code that returns an ordered sequence of values of the same type.
The iterator can be used as a method, operator, or get accessors code body.
The iterator Code uses the yield return statement to return each element in sequence. Yield break terminates iteration.
Multiple iterators can be implemented in the class. Each iterator must have a unique name like any class member and can be called by client code in the foreach statement.
The return type of the iterator must be
Ienumeable, ienumerator, ienumeable <t>, ienumerator <t>
Implementation Code:
Class studentlist
{
String student1 = "";
String student2 = "B ";
String student3 = "C ";
String student4 = "ding ";
String student5 = "E ";
Public string Student1
{
Get {return student1 ;}
Set {student1 = value ;}
}
Public string Student2
{
Get {return student2 ;}
Set {student2 = value ;}
}
Public String student3
{
Get {return student3 ;}
Set {student3 = value ;}
}
Public String student4
{
Get {return student4 ;}
Set {student4 = value ;}
}
Public String student5
{
Get {return student5 ;}
Set {student5 = value ;}
}
// Compile the iterator for this class (implement the system. Collections. ienumerator Interface)
Public System. Collections. IEnumerator GetEnumerator ()
{
// Use the for loop to process the five string-type variables in the StudentList class
For (int I = 0; I <5; I ++)
{
Switch (I)
{
Case 0:
Yield return student1;
Break;
Case 1:
Yield return student2;
Break;
Case 2:
Yield return student3;
Break;
Case 3:
Yield return student4;
Break;
Case 4:
Yield return student5;
Break;
}
}
}
}
In the main function:
// Use the foreach iterator to obtain the field value in the StudentList object
StudentList myStudentList = new StudentList ();
Foreach (object student in myStudentList)
{
Console. WriteLine (student. ToString ());
}
C #3.0 Language Features
Local type inference
Define variable types
Var x = 2.3; // Double
Var s = "sample "; // String
Lambda expressions
Allow the definition of anonymous methods using more concise syntax.
All lambda expressions use the operator "=>" to represent "goes )".
The left part of the operator is the input parameter table, and the right part is the expression or statement block. X => x converts X to X by X ".
Delegate int del (int I );
Del mydelegate = x => X * X;
Int J = mydelegate (5); // J = 25
Extended method extension methods
C # is an object-oriented programming language that allows extension classes to be inherited. However, it is difficult to design a class that can be safely inherited and maintained in the future. Unless the class is designed to be inherited, it can be declared as sealed. However, security conflicts with flexibility.
C #3.0 introduces a syntax that conceptually extends an existing type (either reference or value) by adding new methods without deriving it into a new type.
// Traditional Method
Static class traditional
{
Public static void demo ()
{
Decimal x = 1234.568 M;
Console. WriteLine (FormattedUS (x ));
Console. WriteLine (FormattedIT (x ));
}
Public static string FormattedUS (decimal d)
{
Return String. Format (formatIT, "{0: #, 0.00}", d );
}
Public static string FormattedIT (decimal d)
{
Return String. Format (formatUS, "{0: #, 0.00}", d );
}
Static CultureInfo formatUS = new CultureInfo ("en-US ");
Static CultureInfo formatIT = new CultureInfo ("it-IT ");
}
// Extension Method
Static class ExtensionMethods
{
Public static void Demo ()
{
Decimal x = 1234.568 M;
Console. WriteLine (x. FormattedUS ());
Console. writeline (X. formattedit ());
Console. writeline (formattedus (x); // traditional call allowed
Console. writeline (formattedit (x); // traditional call allowed
}
Static cultureinfo formatus = new cultureinfo ("En-us ");
Static CultureInfo formatIT = new CultureInfo ("it-IT ");
Public static string FormattedUS (this decimal d)
{
Return String. Format (formatIT, "{0: #, 0.00}", d );
}
Public static string FormattedIT (this decimal d)
{
Return String. Format (formatUS, "{0: #, 0.00}", d );
}
}
Object initialization expression object initialization expressions
C #3.0 introduces a shorter form of object initialization syntax that generates functionally equivalent code.
C #3.0 uses a shorter object initialization syntax, which can also implement object initialization.
// Traditional Method
Customer customer = new Customer ();
Customer. Name = "Marco ";
Customer. Country = "Italy ";
// Use Object Initialization Expressions
Customer customer = new Customer {Name = "Marco", Country = "Italy "};
Anonymous type anonymous types
An object initializer can also be used without specifying the class that will be created with the new operator. Doing that, a new class-an anonymous type-is created.
You can use the new operator to initialize an object without declaring the type. This is the anonymous method.
Customer c1 = new Customer {Name = "Marco "};
Var c2 = new Customer {Name = "Paolo "};
Var c3 = new {Name = "Tom", Age = 31 };
Var c4 = new {c2.Name, c2.Age };
Var c5 = new {c1.Name, c1.Country };
Var c6 = new {c1.Country, c1.Name };
The c1 and c2 variables are of the Customer type, and c4, c5, and c6 variables do not have declared types. However, the c4, c5, and c6 types can be introduced from the context of the Code.
Query expressions
C #3.0 also introduces query expression_rs, which have a syntax similar to the SQL language and are used to manipulate data. this syntax is converted into regular C #3.0 syntax that makes use of specific classes, methods, and interfaces that are part of the LINQ libraries. we wocould not cover all the keywords in detail because it is beyond the scope of this chapter. we will cover the syntax of query expression_rs in more detail in Chapter 4, "LINQ Syntax Fundamentals."
In this section, we want to introduce the transformation that the compiler applies to a query expression_r, just to describe how the code is interpreted.
Here is a typical LINQ query:
// Declaration and initialization of an array of anonymous types
Var customers = new [] {
New {Name = "Marco", Discount = 4.5 },
New {Name = "Paolo", Discount = 3.0 },
New {Name = "Tom", Discount = 3.5}
};
Var query =
From c in mers MERs
Where c. Discount> 3
Orderby c. Discount
Select new {c. Name, Perc = c. Discount/100 };
Foreach (var x in query ){
Console. WriteLine (x );
}
A query expression_r begins with a from clause (in C #, all query expression_r keywords are case sensitive) and ends with either a select or group clause. the from clause specifies the object on which LINQ operations are applied, which must be an instance of a class that implements the IEnumerable <T> interface.
That code produces the following results:
{Name = Tom, Perc = 0.035}
{Name = Marco, Perc = 0.045}
C #3.0 interprets the query assignment as if it was written in this way:
Var query = MERs
. Where (c => c. Discount> 3)
. OrderBy (c => c. Discount)
. Select (C => New {C. Name, Perc = C. Discount/100 });