Je devrais vraiment pouvoir l'obtenir, mais je suis juste au point où je pense que ce serait plus facile à demander.
Dans la fonction C #:
public static T GetValue<T>(String value) where T:new()
{
//Magic happens here
}
Qu'est-ce qu'une bonne implémentation pour la magie? L'idée derrière cela est que j'ai du xml à analyser et que les valeurs souhaitées sont souvent primitives (bool, int, string, etc.) et c'est l'endroit idéal pour utiliser des génériques ... mais une solution simple m'échappe pour le moment .
btw, voici un échantillon du xml que j'aurais besoin d'analyser
<Items>
<item>
<ItemType>PIANO</ItemType>
<Name>A Yamaha piano</Name>
<properties>
<allowUpdates>false</allowUpdates>
<allowCopy>true</allowCopy>
</properties>
</item>
<item>
<ItemType>PIANO_BENCH</ItemType>
<Name>A black piano bench</Name>
<properties>
<allowUpdates>true</allowUpdates>
<allowCopy>false</allowCopy>
<url>www.yamaha.com</url>
</properties>
</item>
<item>
<ItemType>DESK_LAMP</ItemType>
<Name>A Verilux desk lamp</Name>
<properties>
<allowUpdates>true</allowUpdates>
<allowCopy>true</allowCopy>
<quantity>2</quantity>
</properties>
</item>
</Items>
Je suggérerais au lieu d'essayer d'analyser XML vous-même, vous essayez de créer des classes qui désérialiseraient du XML dans les classes. Je recommande fortement de suivre la réponse de Bendewey.
Mais si vous ne pouvez pas faire cela, il y a de l'espoir. Vous pouvez utiliser Convert.ChangeType
.
public static T GetValue<T>(String value)
{
return (T)Convert.ChangeType(value, typeof(T));
}
Et utiliser comme ça
GetValue<int>("12"); // = 12
GetValue<DateTime>("12/12/98");
Vous pouvez commencer avec quelque chose comme ceci:
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
if (converter != null)
{
return (T)converter.ConvertFrom(value);
}
Si vous devez analyser des attributs qui sont des types spéciaux, comme des chaînes de couleurs ou de culture ou autres, vous devrez bien sûr créer des cas spéciaux dans ce qui précède. Mais cela gérera la plupart de vos types primitifs.
Si vous décidez de suivre la voie de la sérialisation vers POCO (Plain old CLR Object), il existe peu d'outils qui peuvent vous aider à générer vos objets.
Pour que cela fonctionne correctement, votre méthode générique devra déléguer son travail réel à une classe dédiée.
Quelque chose comme
private Dictionary<System.Type, IDeserializer> _Deserializers;
public static T GetValue<T>(String value) where T:new()
{
return _Deserializers[typeof(T)].GetValue(value) as T;
}
où _Deserializers est une sorte de dictionnaire où vous enregistrez vos classes. (évidemment, une vérification serait nécessaire pour s'assurer qu'un désérialiseur a été enregistré dans le dictionnaire).
(Dans ce cas, où T: new () est inutile car votre méthode n'a besoin de créer aucun objet.
encore une fois avec la mise en garde que faire cela est probablement une mauvaise idée:
class Item
{
public string ItemType { get; set; }
public string Name { get; set; }
}
public static T GetValue<T>(string xml) where T : new()
{
var omgwtf = Activator.CreateInstance<T>();
var xmlElement = XElement.Parse(xml);
foreach (var child in xmlElement.Descendants())
{
var property = omgwtf.GetType().GetProperty(child.Name.LocalName);
if (property != null)
property.SetValue(omgwtf, child.Value, null);
}
return omgwtf;
}
essai:
static void Main(string[] args)
{
Item piano = GetValue<Item>(@"
<Item>
<ItemType />
<Name>A Yamaha Piano</Name>
<Moose>asdf</Moose>
</Item>");
}