我真的应该能够得到这个,但我只是觉得它更容易提问。
在C#函数中:
public static T GetValue<T>(String value) where T:new()
{
//Magic happens here
}
魔术的优秀实施是什么?这背后的想法是我要解析xml并且所需的值通常是基元(bool,int,string等),这是使用泛型的完美地方......但是一个简单的解决方案目前正在躲避我
顺便说一下,这是我需要解析的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>
答案 0 :(得分:149)
我建议您不要尝试自己解析XML,而是尝试创建可以从XML反序列化到类中的类。我会强烈建议遵循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");
答案 1 :(得分:5)
你可以从大致类似的东西开始:
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
if (converter != null)
{
return (T)converter.ConvertFrom(value);
}
如果你必须解析特殊类型的属性,比如颜色或文化字符串或诸如此类的东西,你当然必须在上面构建特殊情况。但这将处理大多数原始类型。
答案 2 :(得分:4)
如果您决定将序列化路线转到POCO(普通旧CLR对象),那么很少有工具可以帮助您生成对象。
答案 3 :(得分:0)
为了使其正常工作,您的通用方法必须将其实际工作委托给专用类。
像
这样的东西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()的位置是无用的,因为你的方法不需要创建任何对象。
答案 4 :(得分:0)
再次警告说,这样做可能是一个坏主意:
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;
}
试运行:
static void Main(string[] args)
{
Item piano = GetValue<Item>(@"
<Item>
<ItemType />
<Name>A Yamaha Piano</Name>
<Moose>asdf</Moose>
</Item>");
}