Some good comments on my last post on guidelines… here is some thoughts on those comments:

 

Roland  asks:

Ø      Attributes: Never use overloaded constructors
What's the reason/idea behind this?

Custom Attributes, unlike other classes, supports optional named arguments. So CA support two ways of doing optional arguments:  overloading and optional named arguments.  Whenever there is a choice such as this it leads to inconsistencies so, we make a recommendation, in this case the value of named arguments makes them a better choice.

 

 

Frans points out:

It must be the case that no one tested that method we added late in the final milestone as an instance method on a sealed class with no constructors. That is right…. I believe this to be a pretty rare instance, but it true.  We have put in a couple of safe guards to avoid this in the future including more formal check-in process, FxCop rules, and even C# language enhancements.

 - Does 'sealing' of classes get you any performance gains when using it on classes with solely static methods?
No, we only seal classes in this case to make their usage more clear.  

- "Always explicitly add a default constructor to avoid versioning issues". This text is also in the library design guidelines in the .NET reference manual, and I first interpreted incorrectly: I thought I should add a default constructor ALWAYS, even if I already had a constructor in place which accepted parameters. Of course that's not necessary.
Yup – you are totally right, I will look at cleaning up the guideline here.

 

Mattias Sjögren suggestions:
In the static classes section, it would be useful to mention the VB.NET Module type. Modules automatically gives you the behavior of a static class, except that it has no constructor, not even a private one, which I'd argue is even better.
Yes, you are right, in fact C# is adding support in a future version as well…

>Use a zeroed state for the default value (such as: 0, 0.0, false, “”, etc.)
Isn't the zeroed state for a string null, not ""?

It is a grey zone.. you are right that technically string is a reference type and whenever the runtime “zeros” a reference type its value becomes “null”.  However from an API design angle we try to avoid returning null for strings (and collections) as it requires extra checking code before operating on the value.  The recommendation is to return String.Empty (“”) in most cases.

 

Frank has some suggestions that are valid… I think CBrumme had a blog about MarshalByRef didn’t he?

Also, to allow better inlining, don't inherit from MarshalByRef, or any of its derived classes: Component, Control, etc. Also Component is heavier than some people realize, and has a finalizer which may never be needed.