Cast object à T

Je suis en train d’parsingr un fichier XML avec la classe XmlReader dans .NET et j’ai pensé qu’il serait judicieux d’écrire une fonction d’parsing générique pour lire différents atsortingbuts de manière générique. Je suis venu avec la fonction suivante:

 private static T ReadData(XmlReader reader, ssortingng value) { reader.MoveToAtsortingbute(value); object readData = reader.ReadContentAsObject(); return (T)readData; } 

Comme je m’en suis rendu compte, cela ne fonctionne pas entièrement comme je l’avais prévu; il génère une erreur avec des types primitifs tels que int ou double , car un transtypage ne peut pas être converti d’une ssortingng en un type numérique. Y a-t-il un moyen pour que ma fonction prévale sous une forme modifiée?

Vérifiez d’abord s’il peut être lancé.

 if (readData is T) { return (T)readData; } try { return (T)Convert.ChangeType(readData, typeof(T)); } catch (InvalidCastException) { return default(T); } 

Avez-vous essayé Convert.ChangeType ?

Si la méthode retourne toujours une chaîne, ce que je trouve étrange, mais c’est d’ailleurs le point, alors peut-être que ce code modifié ferait ce que vous voulez:

 private static T ReadData(XmlReader reader, ssortingng value) { reader.MoveToAtsortingbute(value); object readData = reader.ReadContentAsObject(); return (T)Convert.ChangeType(readData, typeof(T)); } 

essayer

 if (readData is T) return (T)(object)readData; 

Vous pourriez exiger que le type soit un type de référence:

  private static T ReadData(XmlReader reader, ssortingng value) where T : class { reader.MoveToAtsortingbute(value); object readData = reader.ReadContentAsObject(); return (T)readData; } 

Et puis faites une autre qui utilise des types de valeur et TryParse …

  private static T ReadDataV(XmlReader reader, ssortingng value) where T : struct { reader.MoveToAtsortingbute(value); object readData = reader.ReadContentAsObject(); int outInt; if(int.TryParse(readData, out outInt)) return outInt //... } 

Vous pouvez probablement passer, en tant que paramètre, un délégué qui convertira une chaîne en T.

En fait, le problème ici est l’utilisation de ReadContentAsObject. Malheureusement, cette méthode ne répond pas à ses attentes. Bien qu’il devrait détecter le type le plus approprié pour la valeur, il retourne en réalité une chaîne, peu importe ce qui peut être vérifié (ceci peut être vérifié en utilisant Reflector).

Cependant, dans votre cas spécifique, vous connaissez déjà le type auquel vous voulez envoyer, par conséquent, je dirais que vous utilisez la mauvaise méthode.

Essayez plutôt d’utiliser ReadContentAs, c’est exactement ce dont vous avez besoin.

 private static T ReadData(XmlReader reader, ssortingng value) { reader.MoveToAtsortingbute(value); object readData = reader.ReadContentAs(typeof(T), null); return (T)readData; } 

Ajoutez une contrainte de classe (ou plus détaillée, comme une classe de base ou une interface de vos objects T exepected):

 private static T ReadData(XmlReader reader, ssortingng value) where T : class { reader.MoveToAtsortingbute(value); object readData = reader.ReadContentAsObject(); return (T)readData; } 

ou where T : IMyInterface ou where T : new() , etc

En fait, les réponses soulèvent une question intéressante, à savoir ce que vous voulez que votre fonction fasse en cas d’erreur.

Peut-être serait-il plus logique de le construire sous la forme d’une méthode TryParse qui tente de lire dans T, mais renvoie false si cela n’est pas possible?

  private static bool ReadData(XmlReader reader, ssortingng value, out T data) { bool result = false; try { reader.MoveToAtsortingbute(value); object readData = reader.ReadContentAsObject(); data = readData as T; if (data == null) { // see if we can convert to the requested type data = (T)Convert.ChangeType(readData, typeof(T)); } result = (data != null); } catch (InvalidCastException) { } catch (Exception ex) { // add in any other exception handling here, invalid xml or whatnot } // make sure data is set to a default value data = (result) ? data : default(T); return result; } 

edit: maintenant que j’y pense, dois-je vraiment faire le test convert.changetype? la ligne as ne tente-t-elle pas déjà de faire cela? Je ne suis pas sûr que faire cet appel de changement de type supplémentaire accomplisse réellement quelque chose. En fait, cela pourrait simplement augmenter la charge de traitement en générant des exceptions. Si quelqu’un connaît une différence qui en vaut la peine, merci de poster!