Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从字符串转换为<;T>;_C#_Xml_Generics - Fatal编程技术网

C# 从字符串转换为<;T>;

C# 从字符串转换为<;T>;,c#,xml,generics,C#,Xml,Generics,我真的应该能够得到这个,但我只是到了我认为更容易问的地步 在C#函数中: public static T GetValue<T>(String value) where T:new() { //Magic happens here } publicstatict GetValue(字符串值),其中T:new() { //魔法在这里发生 } 魔术的好实现是什么?这背后的想法是,我需要解析xml,所需的值通常是原语(bool、int、string等),这是使用泛型的完美地方。。

我真的应该能够得到这个,但我只是到了我认为更容易问的地步

在C#函数中:

public static T GetValue<T>(String value) where T:new()
{
   //Magic happens here
}
publicstatict GetValue(字符串值),其中T:new()
{
//魔法在这里发生
}
魔术的好实现是什么?这背后的想法是,我需要解析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>

钢琴
雅马哈钢琴
假的
真的
钢琴长凳
黑色钢琴长凳
真的
假的
www.yamaha.com
台灯
荧光台灯
真的
真的
2.

我建议您不要自己解析XML,而是尝试创建将XML反序列化到类中的类。我强烈建议遵循Bendwey的答案

但如果你不能做到这一点,就有希望。你可以用

publicstatict GetValue(字符串值)
{
return(T)Convert.ChangeType(value,typeof(T));
}
像这样使用

GetValue<int>("12"); // = 12
GetValue<DateTime>("12/12/98");
GetValue(“12”);//=12
GetValue(“1998年12月12日”);

您可以大致从以下内容开始:

TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
if (converter != null)
{
   return (T)converter.ConvertFrom(value);
}

如果您必须解析特殊类型的属性,比如颜色、区域性字符串或诸如此类的属性,那么您当然必须在上面构建特殊情况。但这将处理大多数基本类型。

要使其正常工作,您的泛型方法必须将其实际工作委托给专用类

差不多

private Dictionary<System.Type, IDeserializer> _Deserializers;
    public static T GetValue<T>(String value) where T:new()
    {
       return _Deserializers[typeof(T)].GetValue(value) as T;
    }
private Dictionary\u反序列化程序;
公共静态T GetValue(字符串值),其中T:new()
{
将_反序列化器[typeof(T)].GetValue(value)返回为T;
}
where\u反序列化器是一种字典,您可以在其中注册类。(显然,需要进行一些检查以确保反序列化程序已在字典中注册)


(在这种情况下,where T:new()是无用的,因为您的方法不需要创建任何对象。

如果您决定采用序列化到POCO(普通旧CLR对象)的路线,那么很少有工具可以帮助您生成对象

  • 您可以使用生成基于XML定义的.cs文件
  • 中有一个新功能,称为“粘贴为Html”。此功能非常酷,允许您获取剪贴板中的Html块,然后当您将其粘贴到cs文件时,它会自动将xml转换为CLR对象以进行序列化

再次警告,这样做可能是个坏主意:

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;
}
类项目
{
公共字符串ItemType{get;set;}
公共字符串名称{get;set;}
}
公共静态T GetValue(字符串xml),其中T:new()
{
var omgwtf=Activator.CreateInstance();
var xmlement=XElement.Parse(xml);
foreach(xmlElement.subjects()中的var子级)
{
var property=omgwtf.GetType().GetProperty(child.Name.LocalName);
if(属性!=null)
SetValue(omgwtf,child.Value,null);
}
返回omgwtf;
}
试运行:

static void Main(string[] args)
{
    Item piano = GetValue<Item>(@"
        <Item>
            <ItemType />
            <Name>A Yamaha Piano</Name>
            <Moose>asdf</Moose>
        </Item>");
}
static void Main(字符串[]args)
{
Item piano=GetValue(@)
雅马哈钢琴
asdf
");
}

你能提供一个你试图解析的XML样本吗?你想提供一个你期望得到的样本吗?在这种情况下,可能有很多东西……你将字符串转换成字符串的能力将取决于你能定义什么是允许的。如果没有where类restri,你不能在泛型类型上使用as运算符Action.woops,我不知道那一个。我想你仍然可以做一个常规演员阵容?我会看到你的+1,再给你一个+1。虽然我对它的优雅感到困惑,但这闻起来像是为了泛型而使用泛型。让我们来讨论一下GetValue()和(int)GetValue()的美学:PSerialization对于此函数的预期用途是不可能的。我们最初考虑了Xml poco,但当Xml达到>1Mb范围时,它会使应用程序陷入困境。因此xpath是一种可行的方法。这是可行的,但不适用于可空类型。检查解决方案。对于此函数的预期用途,序列化是不可能的。起初我们考虑过Xml poco,但当Xml达到>1Mb的范围时,它会让应用程序陷入困境。老板说xpath是goLINQ到Xml的方法,比xpath快。看,xpath使用DOM,Linq到Xml使用“拉解析”记住,我们中的一些人会在.net 2.0世界中停留一段时间…:-)哎哟,听到这个消息我非常难过。如果你使用GetConverter(typeof(T)),你不需要T变量或new()是的,我很快就把它粗略地写出来了。也许我会给它一个编辑-谢谢。
static void Main(string[] args)
{
    Item piano = GetValue<Item>(@"
        <Item>
            <ItemType />
            <Name>A Yamaha Piano</Name>
            <Moose>asdf</Moose>
        </Item>");
}