What is the purpose of the delegates are immutable in c#? - c#

I was reading a book illustrated C # 2012 in the section Combining Delegates point not notice that? Purpose of the delegates are immutable.
Combining Delegates
All the delegates you’ve seen so far have had only
a single method in their invocation lists. Delegates can be “combined”
by using the addition operator. The result of the operation is the
creation of a new delegate, with an invocation list that is the
concatenation of copies of the invocation lists of the two operand
delegates. For example, the following code creates three delegates.
The third delegate is created from the combination of the first two.
MyDel delA = myInstObj.MyM1;
MyDel delB = SClass.OtherM2;
MyDel delC = delA + delB; // Has combined invocation list
Although the term combining delegates might give the impression that
the operand delegates are modified, they are not changed at all. In
fact, delegates are immutable. After a delegate object is created, it
cannot be changed. Figure 15-6 illustrates the results of the
preceding code. Notice that the operand delegates remain unchanged.

Thread-safety and speed are the primary concerns here. A delegate update is not atomic, it requires updating 6 fields and a list. Making it atomic so it cannot get corrupted requires a lock, far too expensive for such a basic operation that rarely needs to be thread-safe.
By making it immutable, the delegate object cannot get corrupted since it always sets fields on an object that nobody has a reference to yet. Reassigning the delegate object reference is atomic, a basic .NET memory model guarantee. So no need for a lock anymore. The trade-off is less efficient memory use, it is a small penalty.
Do keep in mind that the thread-safe delegate update does not automatically make your code thread-safe as well. The test-and-fire code needs to copy the reference to avoid NRE and you can make a callback to a method that was already unsubscribed.

Delegates are pointers to a method, either concrete or anonymous (well, even anonymous methods are compiled with some compiler-generated identifier).
Would be reasonable that something that points to some concrete thing be mutable? I don't think so. Each instance represents a pointer to some method. Do you want to point to some other method? Create a new pointer. That is, you instantiate a new delegate.
In the other hand, the addition of two or more delegates has this result because + operator can be overloaded. That is, delegates can be part of an addition but internally +'s overload is creating a new delegate with an invocation list.

Related

Implementation of delegates: different approach?

I've just learned about how delegates are implemented from the book CLR via C#:
A delegate object has two parts: closure (target + function pointer), and
invocation list. One object uses only one of them.
Combining non-null delegates using Delegate.Combine always create a new delegate object with a new invocation list that contains all combined delegates.
Delegate.Remove create two objects as well when there are still multiple delegates to call.
Delegate.Combine and Delegate.Remove are default implementation for event DelegateType.
I have some questions on it:
Is this behaviour common for .net runtime? Is there a different implementation?
Invocation list seems to be an array. It's copied everywhere. Why not simply modify array elements, list List<T>?
It seems that using HashSet<DelegateType> instead of event DelegateType gets much better performance: reducing add/remove complexity and GC pressure. What's the cost?

Why anonymous methods inside structs can not access instance members of 'this'

I have a code like the following:
struct A
{
void SomeMethod()
{
var items = Enumerable.Range(0, 10).Where(i => i == _field);
}
int _field;
}
... and then i get the following compiler error:
Anonymous methods inside structs can not access instance members of 'this'.
Can anybody explains what's going on here.
Variables are captured by reference (even if they were actually value-types; boxing is done then).
However, this in a ValueType (struct) cannot be boxed, and hence you cannot capture it.
Eric Lippert has a nice article on the surprises of capturing ValueTypes. Let me find the link
The Truth About Value Types
Note in response to the comment by Chris Sinclair:
As a quick fix, you can store the struct in a local variable: A thisA = this; var items = Enumerable.Range(0, 10).Where(i => i == thisA._field); – Chris Sinclair 4 mins ago
Beware of the fact that this creates surprising situations: the identity of thisA is not the same as this. More explicitly, if you choose to keep the lambda around longer, it will have the boxed copy thisA captured by reference, and not the actual instance that SomeMethod was called on.
When you have an anonymous method it will be compiled into a new class, that class will have one method (the one you define). It will also have a reference to each variable that you used that was outside of the scope of the anonymous method. It's important to emphasize that it is a reference, not a copy, of that variable. "lambdas close over variables, not values" as the saying goes. This means that if you close over a variable outside of the scope of a lambda, and then change that variable after defining the anonymous method (but before invoking it) then you will see the changed value when you do invoke it).
So, what's the point of all of that. Well, if you were to close over this for a struct, which is a value type, it's possible for the lambda to outlive the struct. The anonymous method will be in a class, not a struct, so it will go on the heap, live as long as it needs to, and you are free to pass a reference to that class (directly or indirectly) wherever you want.
Now imagine that we have a local variable, with a struct of the type you've defined here. We use this named method to generate a lambda, and let's assume for a moment that the query items is returned (instead of the method being void). Would could then store that query in another instance (instead of local) variable, and iterate over that query some time later on another method. What would happen here? In essence, we would have held onto a reference to a value type that was on the stack once it is no longer in scope.
What does that mean? The answer is, we have no idea. (Please look over the link; it's kinda the crux of my argument.) The data could just happen to be the same, it could have been zeroed out, it could have been filled by entirely different objects, there is no way of knowing. C# goes to great lengths, as a language, to prevent you from doing things like this. Languages such as C or C++ don't try so hard to stop you from shooting your own foot.
Now, in this particular case, it's possible that you aren't going to use the lambda outside of the scope of what this refers to, but the compiler doesn't know that, and if it lets you create the lambda it has no way of determining whether or not you expose it in a way that could result in it outliving this, so the only way to prevent this problem is to disallow some cases that aren't actually problematic.

What's the deal with delegates?

I understand delegates encapsulate method calls. However I'm having a hard time understanding their need. Why use delegates at all, what situations are they designed for?
A delegate is basically a method pointer. A delegate let us create a reference variable, but instead of referring to an instance of a class, it refers to a method inside the class. It refers any method that has a return type and has same parameters as specified by that delegate. It's a very very useful aspect of event. For thorough reading I would suggest you to read the topic in Head First C# (by Andrew Stellman and Jennifer Greene). It beautifully explains the delegate topic as well as most concepts in .NET.
Well, some common uses:
Event handlers (very common in UI code - "When the button is clicked, I want this code to execute")
Callbacks from asynchronous calls
Providing a thread (or the threadpool) with a new task to execute
Specifying LINQ projections/conditions etc
Don't think of them as encapsulating method calls. Think of them as encapsulating some arbitrary bit of behaviour/logic with a particular signature. The "method" part is somewhat irrelevant.
Another way of thinking of a delegate type is as a single-method interface. A good example of this is the IComparer<T> interface and its dual, the Comparison<T> delegate type. They represent the same basic idea; sometimes it's easier to express this as a delegate, and other times an interface makes life easier. (You can easily write code to convert between the two, of course.)
They are designed, very broadly speaking, for when you have code that you know will need to call other code - but you do not know at compile-time what that other code might be.
As an example, think of the Windows Forms Button.Click event, which uses a delegate. The Windows Forms programmers know that you will want something to happen when that button is pressed, but they have no way of knowing exactly what you will want done... it could be anything!
So you create a method and assign it to a delegate and set it to that event, and there you are. That's the basic reasoning for delegates, though there are lots of other good uses for them that are related.
Delegates are often used for Events. According to MSDN, delegates in .NET are designed for the following:
An eventing design pattern is used.
It is desirable to encapsulate a static method.
The caller has no need access other properties, methods, or interfaces on
the object implementing the method.
Easy composition is desired.
A class may need more than one implementation of the methodimplementation of the method
Another well put explanation from MSDN,
One good example of using a
single-method interface instead of a
delegate is IComparable or
IComparable. IComparable declares the
CompareTo method, which returns an
integer specifying a less than, equal
to, or greater than relationship
between two objects of the same type.
IComparable can be used as the basis
of a sort algorithm, and while using a
delegate comparison method as the
basis of a sort algorithm would be
valid, it is not ideal. Because the
ability to compare belongs to the
class, and the comparison algorithm
doesn’t change at run-time, a
single-method interface is ideal.single-method interface is ideal.
Since .NET 2.0 it has also been used for anonymous functions.
Wikipedia has a nice explanation about the Delegation pattern,
In software engineering, the delegation pattern is a design pattern in object-oriented programming where an object, instead of performing one of its stated tasks, delegates that task to an associated helper object. It passes the buck, so to speak (technically, an Inversion of Responsibility). The helper object is called the delegate. The delegation pattern is one of the fundamental abstraction patterns that underlie other software patterns such as composition (also referred to as aggregation), mixins and aspects.
Oversimplified: I'd say that a delegate is a placeholder for a function until that time when something assigns a real function to the delegate. Calling un-assigned delegates throws an exception.
Confusion occurs because there is often little difference made between the definition, declaration, instantiation and the invocation of delegates.
Definition:
Put this in a namespace as you would any class-definition.
public delegate bool DoSomething(string withThis);
This is comparable to a class-definition in that you can now declare variables of this delegate.
Declaration:
Put this is one of function routines like you would declare any variable.
DoSomething doSth;
Instantiation and assignment:
Usually you'll do this together with the declaration.
doSth = new DoSomething(MyDoSomethingFunc);
The "new DoSomething(..)" is the instantiation. The doSth = ... is the assignment.
Note that you must have already defined a function called "MyDoSomething" that takes a string and returns a bool.
Then you can invoke the function.
Invocation:
bool result = doSth(myStringValue);
Events:
You can see where events come in:
Since a member of a class is usually a declaration based upon a definition.
Like
class MyClass {
private int MyMember;
}
An event is a declaration based upon a delegate:
public delegate bool DoSomething(string withWhat);
class MyClass {
private event DoSomething MyEvent;
}
The difference with the previous example is that events are "special":
You can call un-assigned events without throwing an exception.
You can assign multiple functions to an event. They will then all get called sequentially. If one of those calls throws an exception, the rest doesn't get to play.
They're really syntactic sugar for arrays of delegates.
The point is of course that something/someone else will do the assigning for you.
Delegates allow you to pass a reference to a method. A common example is to pass a compare method to a sort function.
If you need to decide at runtime, which method to call, then you use a delegate. The delegate will then respond to some action/event at runtime, and call the the appropriate method. It's like sending a "delegate" to a wedding you don't want to attend yourself :-)
The C people will recognize this as a function pointer, but don't get caught up in the terminology here. All the delegate does (and it is actually a type), is provide the signature of the method that will later be called to implement the appropriate logic.
The "Illustrated C#" book by Dan Solis provides the easiest entry point for learning this concept that I have come across:
http://www.amazon.com/Illustrated-2008-Windows-Net-Daniel-Solis/dp/1590599543
A delegate is typically a combination of an object reference and a pointer to one of the object's class methods (delegates may be created for static methods, in which case there is no object reference). Delegates may be invoked without regard for the type of the included object, since the included method pointer is guaranteed to be valid for the included object.
To understand some of the usefulness behind delegates, think back to the language C, and the printf "family" of functions in C. Suppose one wanted to have a general-purpose version of "printf" which could not only be used as printf, fprintf, sprintf, etc. but could send its output to a serial port, a text box, a TCP port, a cookie-frosting machine, or whatever, without having to preallocate a buffer. Clearly such a function would need to accept a function pointer for the character-output routine, but that by itself would generally be insufficient.
A typical implementation (unfortunately not standardized) will have a general-purpose gp_printf routine which accepts (in addition to the format string and output parameters) a void pointer, and a pointer to a function which accepts a character and a void pointer. The gp_printf routine will not use the passed-in void pointer for any purpose itself, but will pass it to the character-output function. That function may then cast the pointer to a FILE* (if gp_printf is being called by fprintf), or a char** (if it's being called by sprintf), or a SERIAL_PORT* (if it's being called by serial_printf), or whatever.
Note that because any type of information could be passed via the void*, there would be no limit as to what gp_printf could do. There would be a danger, however: if the information passed in the void* isn't what the function is expecting, Undefined Behavior (i.e. potentially very bad things) would likely result. It would be the responsibility of the caller to ensure that the function pointer and void* are properly paired; nothing in the system would protect against incorrect usage.
In .net, a delegate would provide the combined functionality of the function pointer and void* above, with the added bonus that the delegate's constructor would ensure that the data was of the proper type for the function. A handy feature.

Is the following code a rock solid way of creating objects from a singleton?

I've stumbled accross this code in production and I think It may be causing us problems.
internal static readonly MyObject Instance = new MyObject();
Calling the Instance field twice returns two objects with the same hash code. Is it possible that these objects are different?
My knowledge of the CLI says that they are the same because the hash codes are the same.
Can anyone clarify please?
The field will only be initialized once, so you'll always get the same object. It's perfectly safe.
Of course, you have to be careful when using static objects from multiple threads. If the object is not thread-safe, you should lock it before accessing it from different threads.
Yes it is safe - the simplest safe singleton implementation.
As a further point on comparing the hash-code to infer "they're the same object"; since we're talking about reference-types here (singleton being meaningless for value-types), the best way to check if two references point to the same object is:
bool isSame = ReferenceEqual(first, second);
which isn't dependent on the GetHashCode()/Equals/== implementations (it looks at the reference itself).
It is a guarantee provided by the CLR that this will work properly, even when the class is used by multiple threads. This is specified in Ecma 335, Partition II, section 10.5.3.3:
There are similar, but more complex, problems when type initialization takes place in a multi-threaded system. In these cases, for example, two separate threads might start attempting to access static variables of separate
types (A and B) and then each would have to wait for the other to complete initialization.
A rough outline of an algorithm to ensure points 1 and 2 above is as follows:
1. At class load-time (hence prior to initialization time) store zero or null into all static fields of the type.
2. If the type is initialized, you are done.
2.1. If the type is not yet initialized, try to take an initialization lock.
2.2. If successful, record this thread as responsible for initializing the type and proceed to step 2.3.
2.2.1. If not successful, see whether this thread or any thread waiting for this thread to complete already holds
the lock.
2.2.2. If so, return since blocking would create a deadlock. This thread will now see an incompletely initialized
state for the type, but no deadlock will arise.
2.2.3 If not, block until the type is initialized then return.
2.3 Initialize the base class type and then all interfaces implemented by this type.
2.4 Execute the type initialization code for this type.
2.5 Mark the type as initialized, release the initialization lock, awaken any threads waiting for this type to be
initialized, and return.
To be clear, that's the algorithm they propose for a CLR implementation, not your code.
Other answers have commented on the rock safety. Here's some more on your reference to hash codes:
The hash codes being the same implies that the two objects might be considered "equal" - a different concept to "the same". All a hash code really tells you is that, if two objects have different hash codes, they are definitely not "equal" - and therefore by implication definitely not "the same". Equality is defined by the overriding of the .Equals() method, and the contract imposed is that if two objects are considered equal by this method, then they must return the same value from their .GetHashCode() methods. Two variables are "the same" if their references are equal - i.e. they point to the same object in memory.
It's static meaning it belongs to the class, and it's readonly, so I cannot be changed after initialization, so yes you will get the same object.
It will work just fine in this case but if you mark the instance with the [ThreadStatic] attribute then inline initialization won't work and you'll have to use something else, like lazy initialization, in which case you don't have to take care if the operations using the singleton are "thread-safe" as the singleton is per thread.
Regards...
You could be interested in the fact that the laziness of the initialization
could vary.
Jon Skeet suggests to add an empty static constructor if you care about when
the instance is actually initialized.
In order to avoid exposing in a wrong way I provide you with the link about his
article on the Singleton Pattern.
Your question refers to the Fourth (and suggested) singleton pattern implementation discussed in his article.
Singleton: singleton implementation
Inside the article you find a link to a discussion on beforefieldinit and laziness of the initialization.
Your assumption that they are the same because the hash codes are the same is incorrect, GetHashCode() does a comparison on the fields of your object.
Assuming you didn't overload Object.Equals, you can do a simple equals comparison, which is by default a comparison by reference:
MyObject a = MyObject.Instance;
MyObject b = MyObject.Instance;
Console.WriteLine(a == b);
This will output True, by the way, because your singleton implementation is sort of correct. A static readonly field is guaranteed to be assigned only once. However, semantically it would be more correct to implement a property with only a get-accessor and use a private static field as a backing store.

Why can't I call BeginInvoke directly on a method rather than having to assign it to a delegate?

I'm just looking at some of my code and it occurred to me that given,
Action<int> fireMessage = FireMessages;
fireMessage.BeginInvoke(1, r => fireMessage.EndInvoke(r), null);
As I can directly assign a method to a delegate, why can't I just call BeginInvoke on the method directly. The way this code reads suggests that the delegate assignment is redundant.
But calling BeginInvoke directly on the method throws up a compiler exception.
A method isn't a delegate - a delegate is distinct type which references a method - there is actually more information in a delegate than just the method.
Techically, it might be possible for the compiler to wire this up for you and shorten the typing, but I'm actually somewhat thankful that this wasn't done. By forcing you to assign a delegate to a method reference on an object, then invoke the delegate using BeginInvoke, the compiler is forcing you to be more explicit in your desire here.
Calling a delegate via BeginInvoke potentially has some serious side effects - this should be an explicit, purposeful action. Many methods will not behave as expected if they're called in separate threads, and at least this way, you need to know what you're doing in order to work in this manner.
That being said, in .NET 4, I'd recommend changing how you "fire methods" in "background threads". Instead of using Delegate.BeginInvoke, I'd recommend considering changing to using the new Task class:
Task.Factory.StartNew( () => FireMessages(1) );
There are many advantages to the new task library, especially when it comes to error handling, cancellation, prevention of oversubscription on the thread pool, etc.
There is a bit of syntactic sugar here. A delegate is really under the hood an object that wraps your method, and it happens to have the BeginInvoke method defined. The syntactic sugar is that you can assign a "method" to a delegate (without explicitly creating a delegate), but it only works in this context.
I think it is by design. In C# methods are not objects like they are in functional languages, but delegates are.
Delegate constructor is "point of touching" that is supported by C# compiler, and this is single place where method is used as 'method reference' instead of 'method invokation'.
Accessing 'instance's method instance' object using someInstance.Method.SomeMethodOfMethod have confusing syntax, and requires method instance. Some person may expect method instances obtained from the same method of the same object must be also same, and this will requires additional memory usage to store method instance inside object.
The compiler can automatically produce a delegate from a method group if it knows the type of delegate to produce. It cannot, however, infer the type of a delegate based upon a method group because different delegate types are in general not compatible, even if the signatures match. Although there are many situations where the compiler could in fact use any delegate with a particular signature, the compiler has no way of knowing what those situations are. Consequently, method groups are only converted implicitly to delegates in cases where the compiler can identify the delegate type via other means.

Categories

Resources