在c#中将内部类型转换为通用名称/值对

时间:2013-01-30 16:17:31

标签: c# generics

我需要将内部类型转换为通用名称/值对列表。这样我们就可以以一般/标准的方式发送大量信息,而不必担心如果添加新字段则更改模式等。我的问题是如何填充通用结构。

例如内部字段:

[Serializable]
public class Location
{
    public string sAddress { get; set; }
    public string sCity { get; set; }
    public int iZipCode { get; set; }
}

需要转变为:

<AttributeList>
  <Attribute>
    <Name>sAddress</Name>
    <Value>123 ABC Street</Value>
    <DataType>string</DataType>
  </Attribute>
</AttributeList>

重复sCity和iZipCode。

只有我不确定这样做的最佳方式,例如某些字段,例如iZipCode可能无法实例化。

我能想到的唯一方法是让代码在内部数据结构中查找每个特定字段,确保它不为null,然后从包含实际的枚举对象(或其他东西)映射Attribute.Name内部字段名称(如sAddress),然后是值,然后设置类型,因为我知道什么类型,如果字段是我正在寻找它。

如果只有3个字段,这很好,但会有更多,这似乎是一个糟糕的方法,好像添加了一个新字段我需要更新代码 - 更不用说很多了基本上做同样事情的代码。

理想情况下,我希望能够在内部结构中循环使用所有内容,例如:位置,并自动检查字段是否存在,拉出字段的名称,值和类型(如果没有特定的代码)。

我不知道这是否可行,任何建议都将不胜感激!

2 个答案:

答案 0 :(得分:1)

你可以用反射做到这一点。这是一个例子:

PropertyInfo[] properties
properties = typeof(Location).GetProperties(BindingFlags.Public);
StringBuilder sb = new StringBuilder()
foreach (PropertyInfo p in properties)
{
    sb.Append(p.Name)
    sb.Append(p.PropertyType)
    sb.Append(p.GetValue(null,null))
}

显然更改格式以使其适合您。

您需要使用System.Reflection命名空间。

编辑:我刚看到你的编辑,你想要输出为XML。可能值得看XML Serialisation

答案 1 :(得分:1)

这会将您的示例吐出到XML中。如果要支持索引属性,则需要做一些额外的工作:

Location loc = new Location { sAddress = "123 ABC Street",
                              sCity = "Fake City",
                              iZipCode = 12345 };

XDocument doc = new XDocument();
XElement attrList = new XElement("AttributeList");
doc.Add(attrList);

foreach (PropertyInfo propInfo in loc.GetType().GetProperties())
{
    XElement attrRoot = new XElement("Attribute", new XElement("Name") { Value = propInfo.Name });
    object propValue = propInfo.GetValue(loc, null);
    attrRoot.Add(new XElement("Value") { Value = propValue == null ? "null" : propValue.ToString() });
    attrRoot.Add(new XElement("DataType") { Value = propInfo.PropertyType.ToString() });
    attrList.Add(attrRoot);
}