Вы могли бы реализовать интерфейс ISerializable и использовать это "где T: ISerializable", но тогда вам нужно реализовать методы ISerializable в каждом классе. Проверка во время выполнения может искать SerializableAttribute в классе, но тогда у вас нет проверок времени компиляции. Вы можете написать свой собственный интерфейс, который очень мало нужно реализовать, может быть, просто Property и реализовать этот интерфейс в каждом из ваших классов. Что-то вроде ...
public interface ISerializableSet {
bool IsSerializable { get; }
}
Ваша реализация могла бы использовать отражение, чтобы затем выполнить проверку во время выполнения, ваш метод Foo был бы объявлен «где T: ISerializableSet» для проверки времени компиляции.
Вот более полный пример ...
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;
}
}
Вы можете проверить свойство IsSerializable в своем конструкторе и выдать исключение времени выполнения, если кто-то непреднамеренно удалит [Serializable]. Если вы используете модульные тесты, вы можете обнаружить проблемы во время теста.