Delegate (CLI)

Last updated

A delegate is a form of type-safe function pointer used by the Common Language Infrastructure (CLI). Delegates specify a method to call and optionally an object to call the method on. Delegates are used, among other things, to implement callbacks and event listeners. A delegate object encapsulates a reference to a method. The delegate object can then be passed to code that can call the referenced method, without having to know at compile time which method will be invoked.

Contents

A multicast delegate is a delegate that points to several methods. [1] [2] Multicast delegation is a mechanism that provides functionality to execute more than one method. There is a list of delegates maintained internally, and when the multicast delegate is invoked, the list of delegates is executed.

In C#, delegates are often used to implement callbacks in event driven programming. For example, a delegate may be used to indicate which method should be called when the user clicks on some button. Delegates allow the programmer to notify several methods that an event has occurred. [3]

C# code example

Code to declare a delegate type, named SendMessageDelegate, which takes a Message as a parameter and returns void:

delegatevoidSendMessageDelegate(Messagemessage);

Code to define a method that takes an instantiated delegate as its argument:

voidSendMessage(SendMessageDelegatesendMessageDelegateReference){// Call the delegate and any other chained delegates synchronously.sendMessageDelegateReference(newMessage("hello this is a sample message"));}

The implemented method that runs when the delegate is called:

voidHandleSendMessage(Messagemessage){// The implementation for the Sender and Message classes are not relevant to this example.Sender.Send(message);}

Code to call the SendMessage method, passing an instantiated delegate as an argument:

SendMessage(newSendMessageDelegate(HandleSendMessage));

Delegates (C#)

delegatevoidNotifier(stringsender);// Normal method signature with the keyword delegateNotifiergreetMe;// Delegate variablevoidHowAreYou(stringsender){Console.WriteLine("How are you, "+sender+'?');}greetMe=newNotifier(HowAreYou);

A delegate variable calls the associated method and is called as follows:

greetMe("Anton");// Calls HowAreYou("Anton") and prints "How are you, Anton?"

Delegate variables are first-class objects of the form newDelegateType(obj.Method) and can be assigned to any matching method, or to the value null. They store a method and its receiver without any parameters: [4]

newDelegateType(funnyObj.HowAreYou);

The object funnyObj can be this and omitted. If the method is static, it should not be the object (also called an instance in other languages), but the class itself. It should not be abstract, but could be new, override or virtual.

To call a method with a delegate successfully, the method signature has to match the DelegateType with the same number of parameters of the same kind (ref, out, value) with the same type (including return type).

Multicast delegates (C#)

A delegate variable can hold multiple values at the same time:

voidHowAreYou(stringsender){Console.WriteLine($"How are you, {sender}?");}voidHowAreYouToday(stringsender){Console.WriteLine($"How are you today, {sender}?");}NotifiergreetMe;greetMe=HowAreYou;greetMe+=HowAreYouToday;greetMe("Leonardo");// "How are you, Leonardo?"// "How are you today, Leonardo?"greetMe-=HowAreYou;greetMe("Pereira");// "How are you today, Pereira?"

If the multicast delegate is a function or has no out parameter, the parameter of the last call is returned. [5]

Technical implementation details

Although internal implementations may vary, delegate instances can be thought of as a tuple of an object and a method pointer and a reference (possibly null) to another delegate. Hence a reference to one delegate is possibly a reference to multiple delegates. When the first delegate has finished, if its chain reference is not null, the next will be invoked, and so on until the list is complete. This pattern allows an event to have overhead scaling easily from that of a single reference up to dispatch to a list of delegates, and is widely used in the CLI.

Performance

Performance of delegates used to be much slower than a virtual or interface method call (6 to 8 times slower in Microsoft's 2003 benchmarks), [6] but, since the .NET 2.0 CLR in 2005, it is about the same as interface calls. [7] This means there is a small added overhead compared to direct method invocations.

There are very stringent rules on the construction of delegate classes. These rules permit optimizing compilers a great deal of leeway when optimizing delegates while ensuring type safety.[ citation needed ]

See also

Related Research Articles

In software engineering, the mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program's running behavior.

In software design and engineering, the observer pattern is a software design pattern in which an object, named the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created. This is in contrast to a mutable object, which can be modified after it is created. In some cases, an object is considered immutable even if some internally used attributes change, but the object's state appears unchanging from an external point of view. For example, an object that uses memoization to cache the results of expensive computations could still be considered an immutable object.

In computer programming, a parameter or a formal argument is a special kind of variable used in a subroutine to refer to one of the pieces of data provided as input to the subroutine. These pieces of data are the values of the arguments with which the subroutine is going to be called/invoked. An ordered list of parameters is usually included in the definition of a subroutine, so that, each time the subroutine is called, its arguments for that call are evaluated, and the resulting values can be assigned to the corresponding parameters.

In object-oriented programming, delegation refers to evaluating a member of one object in the context of another original object. Delegation can be done explicitly, by passing the sending object to the receiving object, which can be done in any object-oriented language; or implicitly, by the member lookup rules of the language, which requires language support for the feature. Implicit delegation is the fundamental method for behavior reuse in prototype-based programming, corresponding to inheritance in class-based programming. The best-known languages that support delegation at the language level are Self, which incorporates the notion of delegation through its notion of mutable parent slots that are used upon method lookup on self calls, and JavaScript; see JavaScript delegation.

This article compares two programming languages: C# with Java. While the focus of this article is mainly the languages and their features, such a comparison will necessarily also consider some features of platforms and libraries. For a more detailed comparison of the platforms, see Comparison of the Java and .NET platforms.

<span class="mw-page-title-main">Method overriding</span> Language feature in object-oriented programming

Method overriding, in object-oriented programming, is a language feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes. In addition to providing data-driven algorithm-determined parameters across virtual network interfaces, it also allows for a specific type of polymorphism (subtyping). The implementation in the subclass overrides (replaces) the implementation in the superclass by providing a method that has same name, same parameters or signature, and same return type as the method in the parent class. The version of a method that is executed will be determined by the object that is used to invoke it. If an object of a parent class is used to invoke the method, then the version in the parent class will be executed, but if an object of the subclass is used to invoke the method, then the version in the child class will be executed. This helps in preventing problems associated with differential relay analytics which would otherwise rely on a framework in which method overriding might be obviated. Some languages allow a programmer to prevent a method from being overridden.

<span class="mw-page-title-main">Dependency injection</span> Software programming technique

In software engineering, dependency injection is a design pattern in which an object or function receives other objects or functions that it depends on. A form of inversion of control, dependency injection aims to separate the concerns of constructing objects and using them, leading to loosely coupled programs. The pattern ensures that an object or function which wants to use a given service should not have to know how to construct those services. Instead, the receiving 'client' is provided with its dependencies by external code, which it is not aware of. Dependency injection helps by making implicit dependencies explicit and helps solve the following problems:

<span class="mw-page-title-main">C Sharp (programming language)</span> Multi-paradigm (object-oriented) programming language

C# is a general-purpose, high-level multi-paradigm programming language. C# encompasses static typing, strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines.

this, self, and Me are keywords used in some computer programming languages to refer to the object, class, or other entity of which the currently running code is a part. The entity referred to by these keywords thus depends on the execution context. Different programming languages use these keywords in slightly different ways. In languages where a keyword like "this" is mandatory, the keyword is the only way to access data and methods stored in the current object. Where optional, they can disambiguate variables and functions with the same name.

In programming and software design, an event is an action or occurrence recognized by software, often originating asynchronously from the external environment, that may be handled by the software. Computer events can be generated or triggered by the system, by the user, or in other ways. Typically, events are handled synchronously with the program flow; that is, the software may have one or more dedicated places where events are handled, frequently an event loop.

In object-oriented computer programming, an extension method is a method added to an object after the original object was compiled. The modified object is often a class, a prototype or a type. Extension methods are features of some object-oriented programming languages. There is no syntactic difference between calling an extension method and calling a method declared in the type definition.

In object-oriented computer programming, a null object is an object with no referenced value or with defined neutral (null) behavior. The null object design pattern, which describes the uses of such objects and their behavior, was first published as "Void Value" and later in the Pattern Languages of Program Design book series as "Null Object".

JGroups is a library for reliable one-to-one or one-to-many communication written in the Java language.

This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.

This comparison of programming languages compares how object-oriented programming languages such as C++, Java, Smalltalk, Object Pascal, Perl, Python, and others manipulate data structures.

The computer programming language, C#, introduces several new features in version 2.0. These include:

C# 4.0 is a version of the C# programming language that was released on April 11, 2010. Microsoft released the 4.0 runtime and development environment Visual Studio 2010. The major focus of C# 4.0 is interoperability with partially or fully dynamically typed languages and frameworks, such as the Dynamic Language Runtime and COM.

Objective-C is a general-purpose, object-oriented programming language that adds Smalltalk-style messaging to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was selected by NeXT for its NeXTSTEP operating system. Due to Apple macOS’s direct lineage from NeXTSTEP, Objective-C was the standard programming language used, supported, and promoted by Apple for developing macOS and iOS applications until the introduction of the Swift programming language in 2014.

In programming language theory, flow-sensitive typing is a type system where the type of an expression depends on its position in the control flow.

References

  1. Microsoft Developer Network (MSDN) Article, How to: Combine Delegates (Multicast Delegates)(C# Programming Guide), Accessed 5/20/2008
  2. "About Microsoft's "Delegates"". Sun Developer Network. Sun Microsystems. Archived from the original on 10 February 1999.
  3. Wikibooks:C Sharp Programming/Delegates and Events
  4. Mössenböck, Hanspeter (2002-03-25). "Advanced C#: Variable Number of Parameters" (PDF). Institut für Systemsoftware, Johannes Kepler Universität Linz, Fachbereich Informatik. pp. 23–24. Retrieved 2011-08-04.
  5. Mössenböck, Hanspeter (2002-03-25). "Advanced C#: Variable Number of Parameters". Institut für Systemsoftware, Johannes Kepler Universität Linz, Fachbereich Informatik. p. 25. Retrieved 2011-08-04.
  6. Gray, Jan (June 2003). "Writing Faster Managed Code: Know What Things Cost". Microsoft. Retrieved 2007-09-09.
  7. Sturm, Oliver (2005-09-01). "Delegate calls vastly sped up in .NET 2" . Retrieved 2007-09-09.