Tengo una clase existente para serializar y deserializar objetos a/desde XML. Es una clase genérica con un parámetro de tipo único T
cuya única restricción es where T : IXmlSerializable
. Sin embargo, aún quiero poder utilizar esta clase en las clases que no implementan IXmlSerializable
pero tienen el atributo [Serializable]
. ¿Cómo podría hacer esto?Clase de utilidad de serialización genérica C#
Desde mi clase genérica:
public static class XmlSerializationUtils<T> where T : IXmlSerializable
{
public static T DeserializeXml(XmlDocument xml) { ... }
public static XmlDocument SerializeToXml(T toSerialize) { ... }
}
encontré this discussion pero no había solución dada, sólo que no puedo hacer where T : Serializable
. Intentar hacer where T : SerializableAttribute
hace que Visual Studio diga "No se puede usar la clase sellada 'System.SerializableAttribute' como parámetro constraint de tipo".
Editar: basado en Stephen's answer, que eliminan las limitaciones en XmlSerializationUtils<T>
y ha añadido este constructor estático:
static XmlSerializationUtils()
{
Type type = typeof(T);
bool hasAttribute = null != Attribute.GetCustomAttribute(type,
typeof(SerializableAttribute));
bool implementsInterface =
null != type.GetInterface(typeof(IXmlSerializable).FullName);
if (!hasAttribute && !implementsInterface)
{
throw new ArgumentException(
"Cannot use XmlSerializationUtils on class " + type.Name +
" because it does not have the Serializable attribute " +
" and it does not implement IXmlSerializable"
);
}
}
No es una solución poco razonable. –
Sí, estoy de acuerdo, está siendo utilizado por un desarrollador que sabe si la clase que intenta serializar es confiable, si la usa mal, para qué sirven las excepciones, no puede eliminar todos los errores posibles en el momento de la compilación. –
@Ben: no siempre podemos hacerlo, pero sin duda debemos tratar de detectar errores de manera temprana y frecuente. En este caso, no podemos detectarlo en tiempo de compilación, pero si usamos el truco del constructor estático, podemos detectarlo al comienzo del tiempo de ejecución (lo que significa que no se perderá una prueba de humo posterior a la compilación). –