从string转换为<T>
我真的应该能够得到这一点,但我只是想,我认为这将是更容易问。
在C#函数中:
public static T GetValue<T>(String value) where T:new() { //Magic happens here }
什么是一个很好的执行魔术? 这背后的想法是,我有XMLparsing和所需的值往往是原始(布尔,INT,string等),这是一个完美的地方使用generics…但一个简单的解决scheme是逃避我在这一刻。
顺便说一句,这是我需要parsing的XML的示例
<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>
我build议不要尝试自己parsingXML,而是尝试创build将从XML反序列化到类中的类。 我强烈build议遵循bendewey的答案。
但是,如果你不能做到这一点,就有希望。 你可以使用Convert.ChangeType
。
public static T GetValue<T>(String value) { return (T)Convert.ChangeType(value, typeof(T)); }
像这样使用
GetValue<int>("12"); // = 2 GetValue<DateTime>("12/12/98");
你可以从这样的事情开始:
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T)); if (converter != null) { return (T)converter.ConvertFrom(value); }
如果你必须parsing特殊types的属性,比如颜色或者文化string或者什么的,你当然需要在上面构造特殊的例子。 但是这将会处理大部分的原始types。
如果你决定去POCO(Plain old CLR Object)的序列化路线,那么很less有工具可以帮助你生成你的对象。
- 您可以使用xsd.exe根据您的XML定义生成一个.cs文件
- 在WCF REST入门工具包预览版2中有一个新function,名为Paste as Html。 这个function非常酷,可以让你在剪贴板中获取一块HTML文件,然后当你粘贴到一个cs文件时,它会自动将xml转换为CLR对象进行序列化。
为了正确工作,你的generics方法将不得不把它的实际工作委托给一个专门的类。
就像是
private Dictionary<System.Type, IDeserializer> _Deserializers; public static T GetValue<T>(String value) where T:new() { return _Deserializers[typeof(T)].GetValue(value) as T; }
在哪里_Deserializers是一种你注册你的类的字典。 (显然,需要进行一些检查以确保反序列化器已经在字典中注册)。
(在这种情况下,T:new()是无用的,因为你的方法不需要创build任何对象。
再次警告,这样做可能是一个坏主意:
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; }
testing运行:
static void Main(string[] args) { Item piano = GetValue<Item>(@" <Item> <ItemType /> <Name>A Yamaha Piano</Name> <Moose>asdf</Moose> </Item>"); }