private T parseAttr<T>(XElement x, string elemName) { Type type = typeof(T); T parsedValue; try { parsedValue = type.IsEnum ? (T)Enum.Parse(typeof(T), x.Element(elemName).Value) : (T)Convert.ChangeType(x.Element(elemName).Value, typeof(T)); } catch { parsedValue = default(T); } return parsedValue; }
which can be used like this (example is from a LINQ projection):
let picks = from pick in playerPicks.Element("PlayerList").Descendants("Player").Elements("Picks") select new PlayerPick { TickerSymbol = parseAttr<string>(pick, "TickerSymbol"), Status = parseAttr<Status>(pick, "Status"), PickCall = parseAttr<PickCall>(pick, "PickCall"), StartPrice = parseAttr<double>(pick, "StartPrice"), EndPrice = parseAttr<double>(pick, "EndPrice"), StartDate = parseAttr<DateTime>(pick, "StartDate"), EndDate = parseAttr<DateTime>(pick, "EndDate") }
It works on regular types as well as enums. I'm not completely happy with it - "Convert" is generally less useful than .Parse(), but I couldn't figure out how to use Parse with generics on static methods (i.e. (T).Parse()).
Also, it's hardly bulletproof, but I think I may validate the whole XML document first anyway if it doesn't take too long. Not sure if I'll end up using this or not - I was just amazed about how easy this was to write using generics, and thought it might be useful to somebody.