2009-01-26 41 views
5

我正在寻找相当于下面代码的东西,但是对于任何值类型,无需为每种数据类型编码switch语句。 下面的代码不会编译,因为XmlConvert.ToString()没有接受和对象的重载。如何将使用XmlConvert转换为字符串的值类型转换为字符串?

 int intValue = 10; 
     object boxedValue = (object)intValue; 
     string xmlValue = XmlConvert.ToString(boxedValue); 

换句话说,有没有比这更好的办法:

public static string ToXmlString(Type type, object value) { 

     switch(Type.GetTypeCode(type)) { 
      case TypeCode.Int32: 
       return XmlConvert.ToString((int) value); 
      case TypeCode.DateTime: 
       return XmlConvert.ToString((DateTime) value, XmlDateTimeSerializationMode.Unspecified); 
      case TypeCode.Boolean: 
       return XmlConvert.ToString((bool) value); 

      // TODO: Add case for all other value types! 

      default: 
       return value.ToString(); 
     } 
    } 

回答

0

就扔了这一点,在那里,你在试图将业务对象转换为XML?

也许你可能想看看XmlSerialization。如果你在你的业务对象上标记一些属性,.Net会为你做所有的花哨的XML内容:)。

另外,有没有什么原因你为什么拳击你的价值? XmlConvert.ToString()有19个重载,其中许多是基元。

+0

我非常欣赏这张照片,但是我已经通过了XmlSerializer,DataContractSerializer地狱。我甚至和XamlWriter一起玩过。我的值被装箱,因为我通过处理许多数据类型的接口访问它们。 – 2009-01-26 01:59:37

2

所有值类型都固有地可序列化。所以你只需要使用一个XMLSerializer。 像这样的事情会做(根据你的方法):

public static string ToXmlString(Type type, object value) 
{ 
    StringBuilder sb = new StringBuilder(); 
    System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(sb); 
    System.Xml.Serialization.XmlSerializer serial = 
     new System.Xml.Serialization.XmlSerializer(type); 
    serial.Serialize(writer, value); 
} 
+0

有趣的是,如果您使用Reflector追踪到XmlSerializer.Serialize,您最终会找到一个名为SerializePrimitive的方法,该方法有一个大的switch语句,该语句调度到最终调用XmlConvert.ToString的方法,并将对象转换为本机类型。 – 2009-01-26 02:12:56

1

另一种选择是使用反射来看看在做,然后System.Xml.Linq.XContainer.GetStringValue的副本(它的内部不幸)

1

我不得不做相反的转换(字符串到类型)作为我想编写的序列化程序的一部分(避免内置于原因之一)。我正在进行反序列化,这是唯一一个讨论它的帖子,所以我正在用我的答案进行更新,而它仍然是新鲜的。

我使用的方法是使用反射来基本解决我需要做的事情。下面例子中的变量类型是我正在转换的类型的Type对象,E是一个XmlNode,其内容将被转换,newVar是我将返回的模板类型T的一个实例。此片段不承担对T的任何约束(这就是为什么没有直接串分配/ CAST),并假设对象/枚举的处理方式不同(对象和枚举打破这个):

MethodInfo convertMethod; 

if(Type.GetTypeCode(type) != TypeCode.String) 
    convertMethod = typeof(XmlConvert).GetMethod ("To" + type.Name); 
else 
    convertMethod = E.InnerText.GetType().GetMethod("Clone"); 

if(convertMethod == null) 
{ 
    //Error 
} 
else 
{ 
    if(Type.GetTypeCode (type)!= TypeCode.String) 
     newVar = (T)convertMethod.Invoke(null, new object[] { E.InnerText }); 
    else 
     newVar = (T)convertMethod.Invoke (E.InnerText, new object[]{}); 
} 

(字符串需要处理作为一种特殊情况,ToString()做了其他完全不同的事情,并且打破了一切)。

周围的其他方法(按照原来的职位)将是这样的(未测试,如果我写的连载功能,将更新):

MethodInfo convertMethod; 

if(Type.GetTypeCode(type) != TypeCode.String) 
    convertMethod = typeof(XmlConvert).GetMethod ("ToString", new Type[] {typeof(T)}); 
else 
    convertMethod = typeof(string).GetMethod("Clone"); 

if(convertMethod == null) 
{ 
    //Error 
} 
else 
{ 
    string str; 
    if(Type.GetTypeCode (type)!= TypeCode.String) 
     str = (string)convertMethod.Invoke(null, new object[] { Value }); 
    else 
     str = (string)convertMethod.Invoke (Value, new object[]{}); 
} 

在这种情况下,转换是从T到字符串而Value包含我们正在转换的类型T.区别在于我们要求ToString,但用一个T型参数指定函数。这应该是足够独特的。