My generic method needs to serialize the object passed to it, however just insisting that it implements ISerializable doesn\'t seem to work. For example, I have a struct ret
Instead of
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
try
XmlSerializer xmlSerializer = new XmlSerializer(message.GetType());
The only way to know if an object is serializable is to try to serialize it.
In fact, you were asking how to tell if a type "is serializable", but the actual question will be with respect to objects. Some instances of a type may not be serializable even if the type is marked [Serializable]. For instance, what if the instance contains circular references?
You can't do this totally via generic constraints, but you can do a couple things to help:
1) Put the new() constraint on the generic type (to enable the ability to deserialize and to ensure the XmlSerializer doesn't complain about a lack of default ctor):
where T : new()
2) On the first line of your method handling the serialization (or constructor or anywhere else you don't have to repeat it over and over), you can perform this check:
if( !typeof(T).IsSerializable && !(typeof(ISerializable).IsAssignableFrom(typeof(T)) ) )
throw new InvalidOperationException("A serializable Type is required");
Of course, there's still the possibility of runtime exceptions when trying to serialize a type, but this will cover the most obvious issues.
I wrote a length blog article on this subject that you may find helpful. It mainly goes into binary serialization but the concepts are applicable to most any serialization format.
The long and short of it is