Les génériques où T est classe implémentant l'interface
J'ai une interface:
interface IProfile { ... }
...et une classe:
[Serializable]
class Profile : IProfile
{
private Profile()
{ ... } //private to ensure only xmlserializer creates instances
}
...et un gestionnaire de méthode:
class ProfileManager
{
public T Load<T>(string profileName) where T : class, IProfile
{
using(var stream = new .......)
{
var ser = new XmlSerializer(typeof(T));
return (T)ser.Deserialize(stream);
}
}
}
J'attends la méthode à utiliser comme ceci:
var profile = myManager.Load<Profile>("TestProfile"); //class implementing IProfile as T
...et jeter l'erreur de compilation:
var profile = myManager.Load<IProfile>("TestProfile"); //NO! IProfile interface entered!
Cependant tout compile, et seulement des erreurs d'exécution est levée par le XmlSerializer
.
Je pensais que le where T : class
permettrait de s'assurer que seuls des types de classe où elle est acceptée?
Est-il possible de faire le compilateur jeter erreur si IProfile
(ou d'autres interfaces héritant de IProfile
) est entré, et seulement les types de classes de la mise en œuvre de IProfile
sont acceptés?
quelle erreur est renvoyée par
qui n'a pas d'importance. Le problème ici est que
InvalidOperationException{"IProfile ne peut pas être sérialisé, car il ne possède pas de constructeur sans paramètre"}
XmlSerializer
?qui n'a pas d'importance. Le problème ici est que
T
peut être une interface, même si il y a un class
contrainte.InvalidOperationException{"IProfile ne peut pas être sérialisé, car il ne possède pas de constructeur sans paramètre"}
OriginalL'auteur Anders | 2014-03-07
Vous devez vous connecter pour publier un commentaire.
Selon MSDN classe signifie que T doit être un type de référence; cela s'applique également à toute la classe, interface, délégué, ou de type tableau.
Un travail autour consisterait à exiger que met en œuvre le paramètre de moins de constructeur afin:
La seule autre façon peut-être d'utiliser des contrats de code
Peut-être une autre possibilité est de créer une classe de base abstraite et définir la contrainte de la classe de base au lieu de l'interface?
Cela ne fonctionnera pas, car Load<AbstractBase>(...) toujours compiler et lancer une exception à l'exécution. À l'aide de (nouveaux) est le meilleur moyen de contourner cela.
Ah oui, je n'ai pas vraiment y penser.
OriginalL'auteur Bob Vale
Fonctionne pour moi
OriginalL'auteur David Jones