Convert from string to <T>
I really should be able to get this, but I'm just to the point that I think it will be easier to ask.
In C # function:
public static T GetValue<T>(String value) where T:new() { //Magic happens here } What is a good implementation for magic? The idea is that I have xml for parsing and the required values ββare often primitives (bool, int, string, etc.), and this is an ideal place to use generics ... but a simple solution eludes me in the present moment.
btw, here is an xml sample that I will need to parse
<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> I would suggest, instead of trying to parse the XML yourself, you are trying to create classes that will deserialize from XML to classes. I highly recommend the following Bendewey answer.
But if you cannot do this, there is hope. You can use Convert.ChangeType .
public static T GetValue<T>(String value) { return (T)Convert.ChangeType(value, typeof(T)); } And use like that
GetValue<int>("12"); // = 12 GetValue<DateTime>("12/12/98"); 
You can start with something like this:
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T)); if (converter != null) { return (T)converter.ConvertFrom(value); } If you need to parse attributes that are special types, such as colors or culture strings or something else, you will of course have to create special cases in the above. But this will handle most of your primitive types.
If you decide to go the serialization path in POCO (a regular old CLR object), then there are several tools that can help you generate your objects.
- You can use xsd.exe to create the .cs file based on your XML definition
- A new feature has appeared: view WCF REST Starter Kit Preview 2 , called Paste as Html. This function is really cool and allows you to take the HTML block that is in your clipboard, and then when you paste it into the cs file, it will automatically convert the xml to a CLR object for serialization.
For this to work correctly, your generic method will have to delegate its actual work to the allocated class.
Something like
private Dictionary<System.Type, IDeserializer> _Deserializers; public static T GetValue<T>(String value) where T:new() { return _Deserializers[typeof(T)].GetValue(value) as T; } where _Deserializers is a kind of dictionary in which you register your classes. (obviously, some verification will be required to ensure that the deserializer is registered in the dictionary).
(In this case, where T: new () is useless because your method does not need to create any object.
again with the caveat that doing this is probably a bad idea:
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; } test run:
static void Main(string[] args) { Item piano = GetValue<Item>(@" <Item> <ItemType /> <Name>A Yamaha Piano</Name> <Moose>asdf</Moose> </Item>"); }