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.