Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a good practice to use the [Obsolete] attribute to instruct developers no to use parts of an API

Recently I have been writing some serializable object that also deals with specific logic and has specific life-cycle. In order for it to work properly, it has to be instantiated with an appropriate constructor, that takes mandatory arguments. For serialization purposes, however, I must also add a public default constructor.

The object will be publicly available by our API and 3rd party developers should be able to instantiate and use it. Although there will be an appropriate documentation for how to correctly manipulate with that object, it is no guarantee that someone will be tempted to use the incorrect constructor - and then have trouble.

I am looking for a neat way to apply some guidance while the 3rd party developers are writing their code. The Obsolete attribute came to my mind - I could annotate the serialization constructor with an appropriate comment as a message. The message will then appear in the output warnings and direct the developer to the right line of code. Also, the constructor usage will get appropriately highlighted by both Visual Studio and any code inspection add-on used.

What is bothering me in this approach is that the purpose of the Obsolete attribute is quite different. It's semantical meaning is that the decorated item is deprecated and will probably be removed in further versions. In the serialization constructor scenario this is wrong, and there will be a discrepancy between the usage and meaning of this attribute. Not to mention the option "treat warnings as errors" that might be enabled in some development departments...

So, the question is - is it a an acceptable practice for such usage of the attribute? Are there any other legal and universal ways to achieve the same effect (by universal I mean not relying on 3rd party code inspection add-ons and etc. - I do not control who uses the code and what is their setup) ?


In regards to the comments in the answer below, (which is still useful to me), I must clarify that I am using a protected default constructor on an inheritable class. The constructor is there to support XML serialization, but should not be used for initializing the class in business logic. Inheriting classes should call some of the other base constructors and developers writing the inherited classes need to know that. Still, the developers deriving from this code must also have the means to enable XML serialization for their inherited classes if needed.

like image 805
Ivaylo Slavov Avatar asked Feb 10 '13 14:02

Ivaylo Slavov


1 Answers

Hm, I don't think that this is a good solution. However, do you really need a default constructor?

Note that the serialization API has methods to create uninitialized instances without using a constructor at all (see MSDN: FormatterServices.GetUninitializedObject).

Also, the normal custom serialization constructor is not a default constructor but one taking a SerializationInfo and a StreamingContext. If you have some custom serialization, you may also be able to solve your issue by making the default constructor internal and apply a InternalsVisibleToAttribute for the assembly performing the serialization.

like image 136
Lucero Avatar answered Oct 15 '22 07:10

Lucero