views:

91

answers:

4

I want to create a generic method to serizlize a class to text (for use as part of a networking component) The method should be something like:

public string SerializeToText<T>(T DataToSerialize);

The method contents would simply perform the xml serialization and I can do this. What I want to know is if I can check whether T can be serialized: preferably at compile time, but failing that, at run time.

+2  A: 

The single most reliable way to test and see if an object was serializable is to serialize it. If it succeeds then the object was serializable, if it throws then it was not serializable.

Note this is not a predictor of future success but only of past success. It's certainly possible for an object to change it's state in a way to make it no longer serializable. For example

[Serialiable] 
class Foo { 
  public object Field;
}
class Bar { }

var value = new Foo() { Field1 = 42; } // value is serializable
value.Field1 = new Bar();  // value is no longer serializable

I wrote a lengthy blog article on the issues around determining if an object is or is no serializable. It goes over the issues with this type of an approach in depth.

JaredPar
A: 

A class can be enabled for serialization by simply applying an attribute to its definition. And there is no way in C# to make a compile-time error occur because a type lacks an attribute, so no, you can't catch attempts to serialize an unserializable type at compile time.

If you use the standard library methods for serialization, any attempts to serialize classes that don't support it will produce an exception, so you don't need to do anything special to check this at runtime.

Also there's little point making your wrapper method generic. The argument can be of any type, with no constraint that could usefully restrict it, so it might as well be a plain old object.

However, if you avoid the built-in .NET serialization framework, you could develop your own that is compile-time checked. You'd have to use the type system appropriately - that is, define an interface that any serializable type must implement. Then your SerializeToText method would accept a reference to that interface.

interface ICanSerialize
{
    void Serialize(ISerializeMedium m);
}

interface ISerializeMedium
{
    void Serialize(string name, ref int value);
    void Serialize(string name, ref bool value);
    void Serialize(string name, ref string value);
    void Serialize<T>(string name, ref T value) where T : ICanSerialize;
    void Serialize<T>(string name, ref ICollection<T> value) where T : ICanSerialize;

    // etc.
}

A serializable type would look like this:

class C : ICanSerialize
{
    string _firstName;
    bool _happy;

    public void Serialize(ISerializeMedium m)
    {
        m.Serialize("firstName", ref _firstName);
        m.Serialize("happy", ref _happy);
    }
}

Then you just need an implementation of ISerializeMedium. Such a framework imposes type safety on all uses of serialization from the ground up, rather than trying to fit it on afterward, which is impossible.

This all involves a certain amount of wheel-reinventing, but sometimes you need a rounder wheel.

Daniel Earwicker
A: 

Check this out: How to check if an object is serializable in C#

Leniel Macaferi
This property does not determine if a Type is serializable, just that it's marked with the Serializable attribute. It is possible, and in fact not entirely unlilkely, for it to be marked this way but not actulaly serializable
JaredPar
This is the exact answer someone else posted http://stackoverflow.com/questions/81674/how-to-check-if-an-object-is-serializable-in-c
Matt Dearing
@JaredPar - Your answer was really enlightening.
Leniel Macaferi
A: 

Do you refer to this?

if (typeof(T).IsSerializable)
Javier Morillo
See Jared's answer for why it just isn't that simple.
Daniel Earwicker
ok. I was writing my answer while JaredPar was writing his answer, that´s why I haven´t read it before posting.
Javier Morillo
No problem - I must say I don't think you deserved a downvote for this.
Daniel Earwicker
Yeap... I don´t think that I deserved it, either. Thanks
Javier Morillo