Entrusted in C #

xiaoxiao2021-03-06  39

C # delegate Introduction

Published: 2004-10-9

Author: Stanley B. Lippman from Ark Blog [Yi Xu: This is an old article. However, there is no doubt that lippman is incorporated by Delegate. ] If you want to compare C # with other "C family" language, C # is a unusual characteristic, which does not have a true meaning in C or Java. -------------------------------------------------- ---------------------------- C # is a controversial emerging language, which is created by Microsoft as its Visual Studio. Net's cornerstone is currently in the first beta release phase. C # combines many features derived from C and Java. Java community to C # primary criticism is that it claims that C # is just a java clone version - and it is said that it is the result of a litigation. In the C community, the main criticism (also targeting Java) is, C # is just another flooded private language (YET ANOTHER OVER-HYPED ProPrietary Language). This purpose is to show a language characteristic of C #, and similar features are not directly supported in C or Java. This is the C # Delegate type, which operates approximates a pointer to the member function. I think that C # delegate is deeply thoughtful innovative language features, C programmers (no matter what idea to C # or Microsoft) should have special interests on this feature. In order to stimulate discussions, I will be elaborated around a Testharness Class. This Testharness Class enables any category to register Static or Non-Static's Class Methods for subsequent execution. DELEGATE is the core of Testharness Class. C # Delegate TypedLeGate is a function pointer, but the main difference is three: 1) A Delegate Object can be equipped with multiple methods (Methods) [Methods 1], not once. When we evoke a Delegate equipped with multiple methods, all methods were evokeed in turn - waiting for us to see how to do this. 2) A method of delegate Object (Methods) does not need to be the same category. All methods (Methods) equipped with Delegate Object must have the same prototypes and forms. However, these methods can be STATIC and Non-Static, can be composed of one or more different categories of members.

3) A declaration of Delegate Type is essentially a new Subtype Instance, which is derived from the .NET Library Framework's Abstract Bases Delegate or MulticastDelegate, which provides a set of public methods to inquire DELEGATE OBJECT or it is equipped Method Declaration Delegate Type declaration is generally consisting of four parts: (a) Access level; (b) keyword delegate; (c) return type, and declaration form of the method of Delegate Type (S) DELEGATE TYPE name, is placed between the return type and method of the declaration form (Signature). For example, the following declares a method for "no parameters and VOID return type": public delegate void action (); look at it, this is an amazing similarity; the only difference is More delegate keywords. The purpose of increasing this key is to distinguish between keywords - ratherd-than numerals - to distinguish between the common member functions from other forms of syntax. This has Virtual, Static, and Delegate used to distinguish the grammatical forms of various functions and form functions. If a delegate Type is only equipped with a single method (Method), it can be equipped with any return type and form-based member function. However, if a Delegate Type is equipped with multiple methods at the same time, the return type must be Void [Translation 2]. For example, ACTION can be used to mount one or more methods (Method). In Testharness Class implementation, we will use the above Action declaration. Delegation delegate Handle we can't declare global objects in C #; each object definition must be one of the following: local objects; or other object members; or parameters in the function parameter list. Now I only show you the declaration of Delegate Type. After we will see how to declare it as a member of the category. DELEGATE TYPE in C # is the same as Class, Interface, and Array Types, belonging to Reference Type. Each Reference Type is divided into two parts: a named handle (named handle), manipulated by us; and a unsamed object of the type of the handle, which is indirectly manipulated by the handle. This object must be created via NEW. Define the Reference Type is a "two steps" process. When we write: action theaction;, theAction represents a Handle (handle) of "Delegate Type Action", which is not delegate object. By default, it is set to NULL.

If we try to use it before it is assigned (the translation: Assigned, that is, the corresponding type of object is attachment), the compile period is used. E. However, unless it is defined, it is not conditionally assigned (the translation: Assigned, which is an attachment with the corresponding object), otherwise the statement will trigger the compile period error and print the relevant information. For the Delegate Object Assignment Space In this section, in order to continue to explain with the minimum involvement, we need to access a static method and a non-static method (Non-Static Method), so I use an Announce Class. This category Announcedate static method is printed in the form of long form (using a full single length of length) Prints the current date to standard output devices: Monday, February 26, 2001 non-static method (Non-Static Method) AnnounceTime Take Short Form's form (smaller representation) Print Current time to standard output devices: 00: 58 The first two numbers represent the hour, start calculation from the time of midnight, the last two numbers represent minutes. Announce Class uses the DateTime Class provided by the .NET Class Framework. The definition of the Announce category is as follows. public class Announce {public static void announceDate () {DateTime dt = DateTime.Now; Console.WriteLine ( "Today '' '' s date is {0}", dt.ToLongDateString ());} public void announceTime () { DateTime DT = DateTime.Now; "THE CURRENT TIME NOW IS {0}", DT.ToshostTimeString ());}} To make theAction to be equipped with the above method, we must create an action delegate Type using a New expression. The translation: that is, create a class of objects).

To be equipped with a static method, the quota of the incoming constructor consists of three parts: the name of the class belongs; the name of the method; Dot Operator with two names (.): TheAction = new action (announce.announcedate); To be equipped with a non-static method, the quotes of the incoming constructor are also composed of three parts: the name object name belonging to the method; the name of the method; Dot Operator separated by two names (.): Announce an = new announce () , theAction = new action; It can be noted that theAction is directly assigned, no check in advance (for example, check whether it has referred to whether it is an object in a heap, if so, remove the object first). In C #, the object existing in the Managed HEAP (hosted stack) is applied to garbage collection operations due to the operating period environment (GARBAGE Collected). We don't need to explicitly delete those objects allocated via NEW expression. In the managed heap (hosted stack of procedures), the New expression can be assigned a Hellouser MyProg = New Hellouser () or an array object [] Messages = New String [4]; The form of the assignment statement is: the name of the type, followed by the keyword NEW, followed by a pair of circular projections (represent a single object) or square bracket (represent array object) [1]. (A universal feature in C # language design is to adhere to the use of a single clear form to distinguish between different functions: Garbage Collection (garbage collection) as described in the array object, when we are in Managed HEAP The hosted stack is assigned a space for the Reference Type: int [] FIB = New Int Int "{1, 1, 2, 3, 5, 8}; object automatic maintenance" pointing to its handle (Handles) number. In this example, an associated reference counter is initialized to 1 by the array object pointing to the FIB. If we now initialize another handle, it points to the array object referred to in FIB: int [] notfib = fib; this initialization causes a ShaLLow Copy (shallow copy) of the index group object referred to in the FIB. That is to say, NOTFIB now also points to an array object pointing to the FIB. The reference count associated with the array object becomes 2. If we modify an element in an array via NOTFIB, such as NOTFIB [0] = 0; this change is also visible to FIB. If this multi-access method for the same object is not required, we need to write code and make a Deep Copy (deep copy). For example, // assign another array object notfib = new int [6]; // Start with the 0th element of NOTFIB, // copy the elements in the FIB to the Notfib sequentially. // See Note [2] Fib.copyTo (NOTFIB, 0); NOTFIB now does not refer to the object referred to in FIB. It was previously subjected to the reference number of the associated reference count of two simultaneous points.

The initial reference count of the object referred to in NOTFIB is 1. If we now also re-value the Fib is a new array object - for example, an array containing the first 12 values ​​of the Fibonacci number: FIB = New int [12] {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144}; for the array object previously referred to by FIB, its current reference count turns 0. In the Managed Heap, when the garbage collector is active, the reference count is 0 is deleted. Definition Class Properties now lets us declare the delegate Object as a private static member of Testharness Class. For example [3], public class weid Action (); static private action; // ...} Next We have to provide read and write access mechanisms for this Delegate member. In C #, we don't provide an explicit inline method (inline methods) to read and write non-public data members. Instead, we provide GET and SET Visits (ACCESSORS) for the name of the name. Here is a simple delegate property. We may wish to be called Tester: Public Class Testharness {static public action;} set {activity = value;}} // ...} Property can package static data members, or Package non-static data members. Tester is a Static Property (Static Properties) of Delegate Type Action. (You can notice. We will define Accessor as a code block. The bundle is generated inside the compiler that generates the inline method.) GET must be used as the model of the Property. In this example, it returns directly to the encapsulated object. If "lazy allocation" is used, GET can be constructed and stored in the first time being raised, in order to use. Similarly, if we want Property to support write access, we offer SET Accessor. Value in the set is a conditional keyword (CONDitional-Keyword). That is, Value has predefined meaning only in Set Property (the translation note: That is, Value is only seen as a key in the set code segment): it always represents "The Property" "Object. In our example, Value is an action of an action. During operation, it is bound to the right of assignment expressions.

In the following example, announce an = new announce (); testharnes.tester = new testharness.Action (An.announceTime); SET is expanded to Tester in the inline). The Value object is set to an object returned by a New expression. Evil Delegate Object As before, you have to evoke the method of delegate, we have applied Call Operator for Delegate: Testharness.Tester (); this sentence called Tester Property Get Accessor; Get Accessor Return to TheAction Delegate Handle. If theaction does not point to a delegate Object at this moment, it will have an exception thrown. Decree actions from the outside of the category (delegate-test-and-execute, first implementing proxy, re-test, final implementation) as follows: IF (Testharness.Tester! = Null) Testharness.Tester (); for TestharnesS Class, our method is only simple to encapsulate such tests: static public void run () {if (theAction! = null) THEACTION ();} Associated multiple delegate Objects To make a delegate equipped with multiple methods, we mainly use = Operator and - = Operator. For example, imagine that we define a TestHashTable Class. In the constructor, we add each associated test to Testharnes: Public Class testHashtable {public void test1 (); public void test1 (); testhashtable () {testharness.tester = new testharness.action (TEST0); testharnes .Tester = new testharness.action (TEST1);} // ...} Similarly, if we define a TestArrayList Class, we also join the associated test in the Default Constructionor. It can be noted that these methods are static.

public class testArrayList {static public void testCapacity (); static public void testSearch (); static public void testSort (); testArrayList () {testHarness.Tester = new testHarness.Action (testCapacity); testHarness.Tester = new testHarness. Action (TestSearch); Testharness.Tester = New Testharness.Action (Testsort);} // ...} When the testharness.run method is evoked, usually we don't know which one in TesthashTable and TestarrayList is evoked first. This depends on the order of their constructor to be evoked. But we can know that for each category, the order of its method is evoked is the order of the method being joined DELEGATE. Delegate Objects and Garbage Collection exams code segment in the following local scope: {Announce An = new announce (); testharness.tester = new testharness.An (An.announcetime);} When we will be a non-static After the method is added to the Delegate Object, the address, and "of the method are used to evoke the method, and the handle" of the category object is stored. This causes the reference count associated with this category object to be automatically increased. After initialization via NEW expression, the reference count associated with the object in the Managed Heap is initialized to 1. When the AN is transmitted to the delegate Object constructor, the reference count of the Announce object is increased to 2. After walking out of the local role, the AN's survival ends, the reference count is reduced to 1 - Delegate Object also occupies one. The good news is that if a delegate references a method of an object, it can be ensured that the object will be applied until "Delegate Object no longer references the method", it will be applied to garbage collection processing [4]. We don't have to worry that the object will be laid out under his eyes. The bad news is that the object will continue (the translation: this may be unnecessary) until the delegate Object does not reference its method. You can use-= Operator to remove the method from the Delegate Object. For example, the version of the code is correct; in the local scope, AnnounceTime is first set, executed, and then removed from the delegate object. {Announce an = new announce (); action act = new testharness.Action (An.announcetime); testharness.tester = act; testharness.run (); testharness.tester - = act;} Our initial The idea is that a destructive function is implemented to remove the test method added to the constructor.

However, the destructor call mechanism in C # is not large in C [5]. The destructor of the C # will neither be evoked by the end of the object life, and will not be evokes directly because of the release of the last reference handle (Reference Handle). In fact, the destructive function is only called when the garbage collector is garbage collection, and the timing of the garbage collection is generally unpredictable, and even the garbage collection is not implemented. C # regulations, resource-depleting action is put into a method called Dispose, the user can call this method directly: public void dispose () {testharness.tester - = new testharness.action (TESTHARNESS.TESTER - = NEW TESTHARNESS.ACTION (TEST1);} If a certain category defines a desppete, it usually evokes Dispose. Access the underlying category interface let us look back at the previous code: {Announce An = new announce (); action act = new testharness.action (An.announcetime); testharness.tester = act; testharness.run () Testharness.Tester - = act;} Another implementation is that the Tester is now equipped with other methods. If so, save the current delegate list, reset the Tester to ACT, then call Run Finally, the Tester is restored to the original state. We can use the underlying Delegate class interface to know the number of methods actually equipped with Delegate. For example, IF (Testharness.Tester! = Null && testharnest.getinvocationList (). Length! = 0) {action Oldact = testharness.tester; testharness.tester = act; testharness.run (); testharness.tester = Oldact;} else {...} getInvocationList Returns a method of Delegate Class Objects array, each element of the array, represents a method of the Delegate is currently equipped. Length is a property (attribute) of the underlying Array Class. Array Class implements a C # built-in array of semantics [6]. With the Delegate Class's Method Property, we can get all the runtime information of the mutation. If the method is non-static, then we can more acquiring the objects of the method (the translation: that is, the object to which the method belongs to the class of the method) is more efficient.

In the following example, Delegate's methods (methods) and Properties are represented by red: if (Testharness.Tester! = Null) {DELEGATE [] methods = test.tester.getinvocationList (); Foreach (delegate D in Methods) {MethodInfo themection = D.Method; Type Thetarget = D.Target.gettype (); // Ok: Now we can know all the information of Delegate's method}} Summary I hope this article can cause you to interested in C # delegate Type. I think Delegate Type provides an innovative "Poin Class Method" mechanism for C #. Perhaps this article also caused you to be interested in C # languages ​​and .NET Class Framework. A Good Starting Page for Technical Resources Is . An Informative News Group with Microsoft Developer Input Dealing with Both .NET and C # is . of course, questions or comments on C # or this article can be addressed to me at stanleyl@you-niversity.com. Finally, C # is currently in the process of standardization. On October 31, 2000, Hewlett-Packard , Intel, and Microsoft jointly submitted a proposed C # draft standard to ECMA, an international standards body (ECMA TC39 / TG2). The current draft standard and other documentation can be found at . Acknowledgments I would like to thank Josee Lajoie and Marc Briand for their thoughtful review of an earlier draft of this article. Their feedback has made this a significantly better article. I would also like to thank Caro Segal, Shimon Cohen, and Gabi Bayer of you- Niversity.com for providing a safty.net. Note [1] For C programmers, there are two points worth: (a) need to put a pair of cent posterior arcs after the object's type name as Default Construction And (b) square brackets used in arrays to be placed between the type and array names. [2] The array built in C # is an object of the Array Class provided by .NET Class Library. Array Class static methods and non-static methods can be used by C # built-in objects. COPYTO is a non-static method of Array.

转载请注明原文地址:https://www.9cbs.com/read-68625.html

New Post(0)