Social Icons

Menu

Things I learnt reading C# specifications (#1)

Sunday, February 03, 2013

After reading Jon Skeet’s excellent C# in Depth - again (3rd edition - to be published soon) I’ve decide to try and actually read the C# language specification…
Being a sensible kind of guy I’ve decided to purchase the annotated version which only cover topics up to .NET 4 – but has priceless comments from several C# gurus.
After I’ve read a few pages I was amazed to learn that a few things I knew to be true were completely wrong and so I’ve decided to write a list of new things I’ve learnt while reading this book.
Below you’ll find a short list of new things I learnt from reading the 1st chapter:

Not all value types are saved on the stack

Many developers believe that reference types are stored on the heap while value types are always stored on the stack – this is not entirely true.
First it’s more of an implementation detail of the actual runtime and not a language requirement but more importantly it’s not possible – consider a class (a.k.a reference type) which has a integer member (a.k.a value type), the class is stored on the heap and so are it’s members including the value type since its data is copied “by-value”.

What the hell is “protected internal”

If you’ve written more than one class you’ve probably used public/internal and protected access modifier:

class MyClass
{
// Can only be accessed by MyClass
private object a;
// Accessible by MyClass and classes that derive from it
protected object b;
// Accessible by this assembly
internal object c;
// Accessible by everyone
public object d;
}

So what does protected internal means?

Some believe that members marked as “protected internal” are only accessible for classes that derive from MyClass AND are defined at the same assembly in fact it means that classes that derive from MyClass OR are defined on the same assembly as my class can access that member. So it’s just like using internal and protected at the same time – confused yet?

21 comments

Just to clarify, I think it's fine to have a readonly field which is mutable - so long as you know what you're doing. You've got to realize exactly what it means. For example, it's not uncommon in a generally-mutable type to have a readonly field of type List.

When it first came out, in 2003, I printed and read the CSharp Language Specification. I found that it was very well written. It describes all there is to know about C#. Actually, I read it like a roman. This new language fascinated me (I was coming from C++).Other books about C# simply cannot tell more about the language specification. This is why I recommend anybody asking about a good book about C# to simply read this “Bible”. Moreover, he already has it on his hard drive! In his own language (I have it in French with my French VS).

The "protected internal" thing makes sense to me. But I'm not sure why...

Is it because access modifiers allow the programmer to "give" access, as opposed to "deny" access? I assume because a field is 'private' by default you can then "give" certain types of access, and if you want to you can give both 'internal' and 'protected' permissions.

However, I'm not sure. Mainly because I know you can't do this on a property:

private string Name { public get; set;}

But can do this:

public string Name{ get; private set;}

Meaning that you can't restrict access, and then give more inside the property - but you can give access and restrict more inside it.

Here's what I ran into in an application that I did not know until I read it in the specifiction (10.5.5.1 ("Static field initialization") in the 4.0 version of the spec): if you don't have a static constructor, then the time at which static fields are initialized is 'implementation-dependent' prior to the first use of a static field of that class. Although the design of the code that tripped me up was questionable, I learnt to be safe and always use a static constructor if I have static fields.

I just read about this the other day on Eric Lippert's blog here http://blogs.msdn.com/b/ericlippert/archive/2008/04/24/why-can-t-i-access-a-protected-member-from-a-derived-class-part-three.aspx and he does give the argument that it's because it's private by default and therefore you're widening access with the modifiers. I had never thought about it like that - but clearly you have...

[the readonly thing]: It's the pointer to the object which is readonly (which is why you can't replace it). If you make the readonly field an int, or something, then it really is readonly. But with objects, the thing you're pointing at behaves normally (because it kind of has to: it has no way to know that it has to disable half its functionality). It does make sense - but only if you start thinking in machine code...

Coming from C++, I'm really missing the C++ 'const' semantics. C# has 'readonly' and Java has 'final', but as you pointed out, it's not the same. 'readonly' is not half as useful as C++ 'const'. If you know beforehand an object won't change after construction, or inside a certain method, in C++ you should mark it const. It saves a lot of debugging time.

The reason for doing this is that way you know that the list will always be there, no matter if there is anything in it or not. That way you will never have to check for null pointers in your class.You can just type 'foreach(var item in MyList) {}'

Yes you can, protected is usually used in method related context - if you have a method in your class which you want only derviced classes to access. I guess you can "play" with inner classes and their accessability to achive similar results

Well, as a humble amateur coder, I did know about the value types, perhaps because I have also studied java and C++ and each language manages the storage of types differently, and so I did a detailed comparison. I didn't know about the readonly one, but then that isn't how I implement readonly members anyway. I look forward to the next installment! I found Trey Nash' Accelerated C# 2010 excellent for these kinds of tips.

The access modifiers one makes perfect sense to me, as protected internal would constitute a new access type if it was protected AND internal, so it seems logical that it should mean protected OR internal and this is what I would have expected.