You could implement the ISerializable interface and use that "where T : ISerializable" but then you have to implement the ISerializable methods in every class. A run-time check can look for the SerializableAttribute on the class, but then you don't have compile time checks. You could consider writing your own interface that has very little to have to implement, maybe just a Property and implement that interface on each of your classes. Something like...
public interface ISerializableSet {
bool IsSerializable { get; }
}
Your implementation could use reflection then to do a run-time check, your Foo method would be declared "where T : ISerializableSet" for your compile time check.
Here is a more complete example...
public interface ISerializableSet
{
bool IsSerializable { get; }
}
[Serializable]
class SerializableClass : ISerializableSet
{
[NonSerialized]
private bool _runTimeCheck = true;
#region ISerializableSet Members
public bool IsSerializable
{
get {
if(!_runTimeCheck)
return true;
if(0 != (this.GetType().Attributes & System.Reflection.TypeAttributes.Serializable))
return true;
return false;
}
}
#endregion
}
public static class Bar2
{
public static int Foo<T>(T obj) where T : ISerializableSet
{
ISerializableSet sc = obj;
Console.WriteLine("{0}", sc.IsSerializable.ToString());
return 1;
}
}
You could test the IsSerializable property in your constructor and throw a run-time exception in case someone removes [Serializable] inadvertantly. If you are using Unit Tests, you can detect problems at test time.