Ho una classe esistente per serializzare e deserializzare oggetti da/verso XML. È una classe generica con un singolo parametro di tipo T
il cui unico vincolo è where T : IXmlSerializable
. Tuttavia, voglio essere ancora in grado di utilizzare questa classe su classi che non implementano IXmlSerializable
ma hanno l'attributo [Serializable]
. Come potrei andare a fare questo?C# classe di utilità di serializzazione generica
Dalla mia classe generica:
public static class XmlSerializationUtils<T> where T : IXmlSerializable
{
public static T DeserializeXml(XmlDocument xml) { ... }
public static XmlDocument SerializeToXml(T toSerialize) { ... }
}
ho trovato this discussion ma non c'era soluzione data, solo che io non posso fare where T : Serializable
. Provare a fare where T : SerializableAttribute
rende Visual Studio dire "Impossibile utilizzare la classe sealed System.SerializableAttribute" come tipo di parametro vincolo ".
Edit: sulla base di Stephen's answer, ho rimosso i vincoli XmlSerializationUtils<T>
e ha aggiunto questo costruttore statico:
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"
);
}
}
Questa non è una soluzione irragionevole. –
Sì, sono d'accordo, viene usato da uno sviluppatore che sa se la classe che sta cercando di serializzare è serlabile, se la usa male, per quali eccezioni ci sono, non è possibile eliminare ogni bug possibile in fase di compilazione. –
@ Ben: Non possiamo sempre farlo, ma dovremmo sicuramente cercare di catturare i bug in anticipo e spesso. In questo caso, non possiamo prenderlo in fase di compilazione, ma se usiamo il trucco statico del costruttore, possiamo prenderlo all'inizio del tempo di esecuzione (il che significa che un controllo del fumo post-compilazione non mancherà). –