Why do I need a parameterless constructor? [duplicate]
Asked Answered
S

6

6

Possible Duplicate:
Why XML-Serializable class need a parameterless constructor

I'm getting the run-time error as stated below.

Message=OutlookAddIn1.DeviceRegistrationRequest cannot be serialized because it does not have a parameterless constructor.

I'm perfectly clear why (it's said in the error message) and how to solve it (trivial addition of the empty constructor). What I'm not clear about is why it's required. I've found this discussion but it's mainly about MVC, which has nothing to do with my program (which is a console client for CRM Dynamics).

Solicitude answered 24/9, 2012 at 8:27 Comment(1)
not necessarily XML, it is a serializable-in-general, but a sitll very close duplicateBarabarabarabas
B
3

No it is nothing about MVC (sorry, I've misread your post). It is only about plain C#'py object creation. You see, take this class for an example:

public class Why {
    public Why(int x, int y) { }
}

How would the deserializer know what to pass when your object is to be deserialized and constructed? He couldn't guess. Thus, the framework requires that serializable objects have to have parameterless constructors, so it is safe to "just create" and it is your responsibility to make whole state settable via properties.

note: by the way - note that the constructor does not have to be public. Most serializers do very well with private parameterless constructors or none at all, if they implemented to use uninitialized object construction, that is available from Reflection in at least the .Net full profile.

Barabarabarabas answered 24/9, 2012 at 8:30 Comment(4)
It is just a requirement for the XML serialization. It is not a requirement per se. Binary formatter for example doesn't need a parameterless constructor, not even a private one.Imbed
Your last comment is not quite correct: For many other serializers (BinaryFormatter, DataContractSerializer, etc) even a private parameterless constructor is not used (and is not required). Some will use a private constructor, but often even then will not demand it.Twice
Yep, some serializers can do that - because some use "dirty tricks" like creating uninitialized objects :) Still, I like this explanation, as it does not go into too much details and is quite 'natural' in OO senseBarabarabarabas
It sounds very surprising that a constructor that is private and not referred to anywhere in the class containing it will be seen by an external structure (the deserializing object). I'll give it a try and thenks for the good explanation.Solicitude
T
7

Your class only needs a parameterless constuctor because a library you are using (sounds like XmlSerializer, perhaps indirectly) expects and uses that constructor. This is indeed a pretty convenient way to create objects, as it allows:

object obj = Activator.CreateInstance(type);

usage.

However! This is not an inherent demand by all serializers:

  • there are serializers that do not use any constructor (there's another way of creating objects, skipping the constructor step completely)
  • there are serializers that allow you to provide your own factory method for creating new instances
Twice answered 24/9, 2012 at 8:31 Comment(1)
Can you provide serializers do not use any parameterless constructor?while the answer by Jamby says any Serializer Class need a parameterless constructor.Boule
B
3

No it is nothing about MVC (sorry, I've misread your post). It is only about plain C#'py object creation. You see, take this class for an example:

public class Why {
    public Why(int x, int y) { }
}

How would the deserializer know what to pass when your object is to be deserialized and constructed? He couldn't guess. Thus, the framework requires that serializable objects have to have parameterless constructors, so it is safe to "just create" and it is your responsibility to make whole state settable via properties.

note: by the way - note that the constructor does not have to be public. Most serializers do very well with private parameterless constructors or none at all, if they implemented to use uninitialized object construction, that is available from Reflection in at least the .Net full profile.

Barabarabarabas answered 24/9, 2012 at 8:30 Comment(4)
It is just a requirement for the XML serialization. It is not a requirement per se. Binary formatter for example doesn't need a parameterless constructor, not even a private one.Imbed
Your last comment is not quite correct: For many other serializers (BinaryFormatter, DataContractSerializer, etc) even a private parameterless constructor is not used (and is not required). Some will use a private constructor, but often even then will not demand it.Twice
Yep, some serializers can do that - because some use "dirty tricks" like creating uninitialized objects :) Still, I like this explanation, as it does not go into too much details and is quite 'natural' in OO senseBarabarabarabas
It sounds very surprising that a constructor that is private and not referred to anywhere in the class containing it will be seen by an external structure (the deserializing object). I'll give it a try and thenks for the good explanation.Solicitude
G
1

It is required so that code that doesn't know anything about parameterised constructors can construct one of your objects based on the convention that a parameterless constructor is available.

On deserialization, and object instance is required so the deserialization process will create one using this constructor.

Galliard answered 24/9, 2012 at 8:29 Comment(0)
O
1

For deserialization to make an instance. You can do private or internal construcotr if u want to hide it.

Oys answered 24/9, 2012 at 8:30 Comment(0)
S
0

Don't now exact details of an issue reported , but generally talking:

Your serialization need default ctor in order to be able to construct you type's object. If you don't have it, there is not way it can do it. There is no way it can figure out, the right parameter to pass to the ctor with parameters, so it neads "clear" parameter-less ctor.

Senile answered 24/9, 2012 at 8:30 Comment(3)
Actually, very few serializers need a parameterless constructorTwice
@MarcGravell: agree, but the one used by OP seems that one actually that needs it.Senile
My point being the phrasing: "Serialization need default ctor"... well, not quite: a specific serializer might need that, but serialization requires no such thing.Twice
P
0

That's because the deserialiser needs to be able to easilty create an instance of the class and fill it with data.

If there is no parameterless constructor, the deserialiser would have to guess what parameters to send to the constructor. That could work reasonably well if there was a convention to follow on what parameters the constructor should have, but the easiest convention is that there should be a constructor without parameters.

Popgun answered 24/9, 2012 at 8:30 Comment(1)
No, it could create an uninitialized object and fill-in all fields (incl. properties), e.g. object myFoo = FormatterServices.GetUninitializedObject(typeof(Foo));.Devin

© 2022 - 2024 — McMap. All rights reserved.