.NET Internals Cookbook Part 7 — Word tearing, locking and others

This is the seventh part of the .NET Internals Cookbook series. For your convenience you can find other parts in the table of contents in Part 0 – Table of contents

45. Should we always avoid boxing?

Boxing is expensive, it wraps value types into reference instances so we lose some performance. However, take this code:

The only difference between UnsafeParallel and SafeParallel is that the former stores the result in a T variable, the latter stores just an object.

Now, what happens if you use value types? Since they can be bigger than a reference, they do not need to be stored atomically. So if two threads try to write to result at the same time we may get the write tearing. Run the code to see that it is happening indeed — we get mixed content.

However, if we use SafeParallel, the value type is boxed so it is stored atomically (because only reference needs to be stored). Thanks to that we never get broken data.

46. What happens if first delegate method throws an exception?

It stops executing other callbacks, as shown here:

Output:

47. Does foreach require interface? What is a WellKnownMember?

No, as shown here:

foreach requires something with method GetEnumerator returning something with Current and bool MoveNext(). This is a duck typing. The same rule goes for await as shown here:

Actually, there are a lot of WellKnownMember which are used by the compiler.

48. How does LINQ query syntax work? How is it compiled?

They are compiled to normal Where, Select, Join and other methods. Try decompiling the following code:

You should get something similar to:

49. What is the difference between Select in IEnumerable and IQueryable?

This is Enumerable.Select:

This is Queryable.Select:

Apart from different interfaces, they accept lambda in different way. Enumerable gets normal lambda and executes it directly. Queryable takes expression which is just a lambda syntax tree. It is not executed at all, it is later translated to SQL query.

50. How to block access to private members via reflection?

You can use DisablePrivateReflectionAttribute on the assembly level.

You can also use ReflectionPermission.

51. Can you lock a value type?

No and yes (but still no). If you try this:

you will get:

So we cannot just lock it. But we know that lock uses monitors, so let’s try this:

It compiles but crashes, why? This is because we use boxing so we are not locking on the value but on the boxed object. We could store the reference as in here:

This works but now we risk locking on different boxed instance. So generally — don’t do that.