Question

OK, I know what you're thinking, "why write a method you do not want people to use?" Right?

Well, in short, I have a class that needs to be serialized to XML. In order for the XmlSerializer to do its magic, the class must have a default, empty constructor:

public class MyClass
{
  public MyClass()
  {
    // required for xml serialization
  }
}

So, I need to have it, but I don't want people to use it, so is there any attribute that can be use to mark the method as "DO NOT USE"?

I was thinking of using the Obsolete attribute (since this can stop the build), but that just seems kinda "wrong", is there any other way of doing this, or do I need to go ahead and bite the bullet? :)

Update

OK, I have accepted Keith's answer, since I guess in my heart of hearts, I totally agree. This is why I asked the question in the first place, I don't like the notion of having the Obsolete attribute.

However...

There is still a problem, while we are being notified in intellisense, ideally, we would like to break the build, so is there any way to do this? Perhaps create a custom attribute?

More focused question has been created here.

Was it helpful?

Solution

If a class is [Serialisable] (i.e. it can be copied around the place as needed) the param-less constructor is needed to deserialise.

I'm guessing that you want to force your code's access to pass defaults for your properties to a parameterised constructor.

Basically you're saying that it's OK for the XmlSerializer to make a copy and then set properties, but you don't want your own code to.

To some extent I think this is over-designing.

Just add XML comments that detail what properties need initialising (and what to).

Don't use [Obsolete], because it isn't. Reserve that for genuinely deprecated methods.

OTHER TIPS

You can use:

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]

so that it doesn't show up in Intellisence. If the consumer still wants to use it they can, but it won't be as discoverable.

Keiths point about over engineering still stands though.

I read the heading and immediately thought "obsolete atribute". How about

    /// <summary>
    /// do not use
    /// </summary>
    /// <param name="item">don't pass it anything -- you shouldn't use it.</param>
    /// <returns>nothing - you shouldn't use it</returns>
    public bool Include(T item) { 
    ....

I would actually be inclined to disagree with everyone that is advocating the use of the ObsoleteAttribute as the MSDN documentation says that:

Marking an element as obsolete informs the users that the element will be removed in future versions of the product.

Since the generic constructors for XML serialization should not be removed from the application I wouldn't apply it just in case a maintenance developer down the road is not familiar with how XML serialization works.

I have actually been using Keith's method of just noting that the constructor is used for serialization in XML documentation so that it shows up in Intellisense.

You could build your own Attribute derived class, say NonCallableAttribute to qualify methods, and then add to your build/CI code analysis task the check to monitor if any code is using those methods.

In my opinion, you really cannot force developers to not use the method, but you could detect when someone broke the rule as soon as possible and fix it.

Wow, that problem is bugging me too.

You also need default constructors for NHibernate, but I want to force people to NOT use C# 3.0 object initializers so that classes go through constructor code.

throw new ISaidDoNotUseException();

Separate your serializable object from your domain object.

What you're looking for is the ObsoleteAttribute class:

using System;

public sealed class App {
   static void Main() {      
      // The line below causes the compiler to issue a warning:
      // 'App.SomeDeprecatedMethod()' is obsolete: 'Do not call this method.'
      SomeDeprecatedMethod();
   }

   // The method below is marked with the ObsoleteAttribute. 
   // Any code that attempts to call this method will get a warning.
   [Obsolete("Do not call this method.")]
   private static void SomeDeprecatedMethod() { }
}

ObsoleteAttribute will probably work in your situation - you can even cause the build to break if that method is used.

Since obsolete warnings occur at compile time, and since the reflection needed for serialization occurs at runtime, marking that method obsolete won't break serialization, but will warn developers that the method is not there to be used.

I'm using the ObsoleteAttribute.

But also you can have some comments of course.

And finally remove it completely if you can (don't have to maintain the compatibility with something old). That's the best way.

Yep there is.

I wrote this blogpost about it Working with the designer.

And here is the code:


public class MyClass
{
  [Obsolete("reason", true)]
  public MyClass()
  {
    // required for xml serialization
  }
}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top