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.

H H
  • 263,252
  • 30
  • 330
  • 514
ForbesLindesay
  • 10,482
  • 3
  • 47
  • 74
  • Pretty sure this is a dupe and atleast one answer is an exact dupe http://stackoverflow.com/questions/81674/how-to-check-if-an-object-is-serializable-in-c – Matt Dearing Mar 09 '10 at 23:26
  • Nope - this question asks primarily about checking at compile time. That previous question only asks about runtime checking. Many of the answers here may be duplicates, but only because their authors are not reading this question carefully enough! :) – Daniel Earwicker Mar 09 '10 at 23:28

3 Answers3

6

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
  • 733,204
  • 149
  • 1,241
  • 1,454
  • For people interested in the link, this is it: https://learn.microsoft.com/en-us/archive/blogs/jaredpar/is-it-serializable – Krowi Jun 11 '20 at 08:29
1

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
  • 114,894
  • 38
  • 205
  • 284
-1

Do you refer to this?

if (typeof(T).IsSerializable)
Javier
  • 4,051
  • 2
  • 22
  • 20