Ich habe eine vorhandene Klasse zum Serialisieren und Deserialisieren von Objekten zu/von XML. Es ist eine generische Klasse mit einem einzigen Typparameter T
, deren einzige Einschränkung where T : IXmlSerializable
ist. Ich möchte jedoch weiterhin diese Klasse für Klassen verwenden können, die nicht IXmlSerializable
implementieren, aber das [Serializable]
Attribut haben. Wie könnte ich das tun?C# generisches Serialisierungsdienstprogramm Klasse
Aus meiner generischen Klasse:
public static class XmlSerializationUtils<T> where T : IXmlSerializable
{
public static T DeserializeXml(XmlDocument xml) { ... }
public static XmlDocument SerializeToXml(T toSerialize) { ... }
}
Ich fand this discussion aber es gab keine Lösung gegeben, nur, dass ich nicht where T : Serializable
tun können. Der Versuch, where T : SerializableAttribute
zu tun, lässt Visual Studio sagen "Kann die versiegelte Klasse 'System.SerializableAttribute' nicht als Typ-Parameter-Einschränkung verwenden".
Edit: basierend auf Stephen's answer, entfernte ich die Einschränkungen für XmlSerializationUtils<T>
und hinzugefügt, um diese statische Konstruktor:
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"
);
}
}
Das ist keine unangemessene Lösung. –
Ja, ich stimme zu, es wird von einem Entwickler verwendet, der weiß, ob die Klasse, die er zu serialisieren versucht, seriell ist, wenn er sie falsch verwendet, für die Ausnahmen vorgesehen sind, können Sie nicht jeden möglichen Fehler zur Kompilierzeit beseitigen. –
@Ben: Wir können das nicht immer tun, aber wir sollten auf jeden Fall versuchen, Fehler früh und oft zu finden. In diesem Fall können wir es zur Kompilierzeit nicht abfangen, aber wenn wir den Trick des statischen Konstruktors verwenden, können wir ihn zu Beginn der Laufzeit abfangen (was bedeutet, dass eine Prüfung nach der Kompilierung nicht fehlschlägt). –