Through a deep understanding of the core foundation built by C#1, it is possible to know that the C # version has been expanded on the basis of c#1, and these extensions are based on the core of C # construction.
DelegateI. The process of writing a delegate
Delegates are often linked to the C language's "function pointers". Delegation is an important expression of method parameterization and functional language. Write a delegate in c#1 to go through four parts:
1. Declaring delegate type
delegate void Stringprocessor (string param1);
This delegate specifies a method that has no return value and has a parameter of type string.
This delegate inherits from System.MulticastDelegate, which is derived from system.delegate.
The delegate itself is a reference type, so it cannot be declared in a method when the delegate is declared. It can be used as an inner class, or it can be declared under Namaspace.
2., there must be a method that contains the code to be executed, which is consistent with the signature of the delegate declaration, including parameters and return values
In C #, to find a method for a delegate, the signature must be exactly the same as that of the delegate, allowing the hypotenuse and contravariance of the delegate in the C#2. You must have the following delegate:
Delegate Object SayHello (string word);
This delegate can be instantiated by this method:
static string Sayhello (Object Word) { Console.WriteLine (word); return Word. ToString (); }
3. Create the delegate itself
You can use the new operator to create an instance of a delegate:
New SayHello (SayHello);
Delegate-method group conversions are supported in c#2, so you can directly use the
SayHello say = SayHello;
4. Call Delegate
When everything is ready, you can use the Invoke method to complete the call. C # also makes it easier to do this, using
SayHello say = SayHello; Say ("hello,you");
can be done, but behind the scenes the compiler has done some work for you:
Ii. merger and deletion of Delegates
The characteristics of a delegate and string are similar: they are immutable. This is reflected in the merging and deletion of delegates:
There is an action list inside the delegate (invocation list): System.Delegate static method Combine and remove are responsible for creating a new delegate instance. Where combine links the list of operations for two delegates, remove is responsible for deleting an operation for a delegate instance. None of them change the original type (so much like string) they all return a delegate.
Delegate.combine,delegate.remove is rarely called directly in code but with the + = and-= operators. This is also the credit of the compiler:
If an exception is thrown in the invocation list, the method that throws the exception causes the invocation list to not be executed.
If there is a return value, then the invocation list returns the value of the last called method. Therefore, a method with a return value is not typically executed in the invocation list.
However, if necessary, you can execute the method and get the return value by calling Invocationlist.
III. Events
First look at the declaration of the event:
Public Event SayHello sayhelloevent;
The event is a wrapper over the delegate, a bit similar to the relationship between the property and the fallback field, which declares that the compiler will do the following:
1. Declare a private field of the SayHello delegate type in the same scope
2. Declare an attribute-like block structure that contains a property-like accessor and assignment method, named by the compiler, with the prefix "Add" and "Remove", respectively.
3, externally, the event is manipulated via + = and-=, and the access modifier that declares the event restricts the operation. This means that an event cannot be manipulated externally if it is declared as a private event.
4, inside, the + = operator will call the "add" prefix method, the "Add" prefix method calls Delegate.combine to merge the operation, similarly, the-= operator will invoke the "remove" prefix method, The method calls Delegate.remove to delete the operation.
5, from the above can be seen, the event is a pair of children "add" and "Remove" method. He encapsulates the delegate, thus avoiding the caller's direct manipulation of the delegate, but instead indirectly manipulating the delegate through the event, where the delegate can be seen inside the class, and events can be seen outside the class.
To summarize, the event is not a delegate instance, but a Add/remove method in which the paired child appears. Similar to the Get/set method for attributes.
characteristics of the type system
Before c#4, the type system of C # is static, explicit, and secure.
one, static type and dynamic type
C # is statically typed: the type of each variable or expression is known at compile time. Only operations that are known to be of type are allowed. The term static is used to represent the use of immutable type data to analyze which operations are available.
Unlike static types, which are dynamic types, the essence of a dynamic type is that the variable contains a value, but those values are not limited to a particular type. So the compiler cannot perform the same kind of checks.
second, display type and implicit type
This discussion is only established in the context of static language. For an explicit type, each variable specifies the type at the time of declaration. An implicit type allows the use of compiler variables to determine the type of a variable. Whether explicit or implicit, the type of an expression is determined at compile time.
iii. type safety and type insecurity
C # is type-safe, and C # supports some type-safe conversions: inherited, numeric, and, if forced type conversions are used, the compiler detects the result of the conversion and throws an exception to organize the program's continuation, and C # also supports limited covariance and contravariance (C#4). But there is a long distance to real covariance and contravariance.
You can handle some of the constraints on covariance and contravariance by explicitly implementing an interface.
To summarize:
C # 1 is static type--the compiler knows which members you can use;
C # 1 is explicit-you have to tell the compiler what type of variable it is;
C # 1 is secure-you cannot treat one type as another unless there is a real transformation relationship;
Static types still do not allow a collection to be a strongly typed "string list" or "List of integers" unless a large number of duplicate codes are used for different elements;
Method overrides and interface implementations do not allow covariance/contravariance.
value types and reference typesBasic knowledge of value types and reference types
For an expression of a reference type , such as a variable, its value is a reference, not an object.
A reference is like a URL--a small piece of data that allows you to access real information.
for an expression of a value type, its value is the actual data.
Sometimes, value types are more efficient than reference types, sometimes in the opposite direction.
objects of the reference type are always on the heap, and value type values are either on the stack or on the heap, depending on the context.
when a reference type is used as a method parameter, the parameter is passed by default in "value passing"-but the value itself is a reference.
The intrinsic difference between a value type and a reference type is different in the way it is copied: The value type copies the value itself, and the reference type replicates the reference.
Another difference between the two types is that value types cannot derive from other types. One consequence of this is that the value does not require additional information to describe what the value actually is. Comparing it to a reference type, for reference types, the beginning of each object contains a block of data that identifies the actual type of the object and provides some additional information. You can never change the type of an object--when you perform a simple coercion type conversion, the runtime gets a reference to check that the object it references is a valid object of the target type. Returns the original reference if it is valid, or throws an exception. The reference itself does not know the type of the object--so the same reference "value" can be used to (reference) multiple variables of different types. For example, the following code:
Stream stream=New MemoryStream (); = (MemoryStream) stream;
Line 1th creates a new MemoryStream object and sets the value of the stream variable to a reference to that new object. Line 2nd checks that the value of stream refers to a MemoryStream (or derived type) object and sets the value of MemoryStream to the same value.
The value type variable itself stores the value , and the reference type variable itself stores the reference, which contains an address that points to the real object. The value of the variable is stored where it is declared. The value of the local variable is always stored in the stack (the conclusion is fully established in c#1. Later, in a higher version of C #, local variables may end up stored in the heap under certain circumstances. The value of the instance variable is always stored where the instance itself is stored. Reference type instances (objects) are always stored in the heap, and so are static variables.
The difference between passing by value and passing by reference is that the copy is passed by value, and the alias is passed by reference.
The background of boxing is that the value type and the reference type have different values: the value of the value type is the value itself, and the value of the reference type is just a reference.
Values of a value type are boxed when the behavior of a reference type is required, and unpacking is the opposite process.
new features built on top of c#1I. New features related to delegates
C#1, method group conversions, anonymous methods, delegate covariance and inverse-->c#3 lambda expressions, built-in Func, Action, generic interfaces, and covariance of delegates in-->c#2
Ii. characteristics related to the type system
C#2--> generics, delegated covariance and contravariance-->c#3 anonymous types, implicit types, extension methods-->c#4 Limited generics covariance and contravariance, dynamic types
Iii. attributes related to value types
c#2--> generic, nullable<t> nullable value types
C # Review notes (2) The core foundation of--c#1