C# 从字符串转换为 <T>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/732677/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting from String to <T>
提问by Saint Domino
I really should be able to get this, but I'm just to the point where I think it'd be easier to ask.
我真的应该能够得到这个,但我只是到了我认为更容易问的地步。
In the C# function:
在 C# 函数中:
public static T GetValue<T>(String value) where T:new()
{
//Magic happens here
}
What's a good implementation for the magic? The idea behind this is that I have xml to parse and the desired values are often primitives (bool, int, string, etc.) and this is the perfect place to use generics... but a simple solution is eluding me at the moment.
什么是魔术的好实现?这背后的想法是我要解析 xml,并且所需的值通常是基元(bool、int、string 等),这是使用泛型的理想场所……但目前我无法找到一个简单的解决方案.
btw, here's a sample of the xml I'd need to parse
顺便说一句,这是我需要解析的 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>
采纳答案by Samuel
I would suggest instead of trying to parse XML yourself, you try to create classes that would deserialize from the XML into the classes. I would stronglyrecommend following bendewey's answer.
我建议您不要尝试自己解析 XML,而是尝试创建从 XML 反序列化为类的类。我强烈建议遵循本德威的回答。
But if you cannot do this, there is hope. You can use Convert.ChangeType
.
但如果你不能做到这一点,就有希望。您可以使用Convert.ChangeType
.
public static T GetValue<T>(String value)
{
return (T)Convert.ChangeType(value, typeof(T));
}
And use like so
并像这样使用
GetValue<int>("12"); // = 12
GetValue<DateTime>("12/12/98");
回答by womp
You can start with something roughly like this:
你可以从大致这样的事情开始:
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
if (converter != null)
{
return (T)converter.ConvertFrom(value);
}
If you have to parse attributes that are special types, like colors or culture strings or whatnot, you will of course have to build special cases into the above. But this will handle most of your primitive types.
如果您必须解析特殊类型的属性,例如颜色或区域性字符串或诸如此类,您当然必须在上述内容中构建特殊情况。但这将处理您的大部分原始类型。
回答by Denis Troller
For this to work correctly, your generic method is going to have to delegate its actual work to a dedicated 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 some kind of dictionary where you register your classes. (obviously, some checking would be required to ensure a deserializer has been registered in the dictionary).
其中 _Deserializers 是某种字典,您可以在其中注册您的课程。(显然,需要进行一些检查以确保解串器已在字典中注册)。
(In that case the where T:new() is useless because your method does not need to create any object.
(在这种情况下, where T:new() 是无用的,因为您的方法不需要创建任何对象。
回答by bendewey
If you decide to go the route of serialization to POCO (Plain old CLR Object), then there are few tools that can help you generate your objects.
如果您决定采用 POCO(Plain old CLR Object)的序列化路线,那么很少有工具可以帮助您生成对象。
- You can use xsd.exeto generate a .cs file based on your XML Definition
- There is a new feature in the WCF REST Starter Kit Preview 2, called Paste as Html. This feature is really cool and lets you take a block of HTML thats in your clipboard, then when you paste it into a cs file it automatically converts the xml to the CLR object for serialization.
- 您可以使用xsd.exe根据您的 XML 定义生成 .cs 文件
- WCF REST Starter Kit Preview 2 中有一项新功能,称为 Paste as Html。这个功能真的很酷,让您可以在剪贴板中获取一块 HTML,然后当您将其粘贴到 cs 文件中时,它会自动将 xml 转换为 CLR 对象以进行序列化。
回答by Jimmy
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>");
}