I have recently implemented a code to accomplish Object
-to-String
. Can you suggest any pros and cons with regard to the code?
public static string ObjectToXml(object obj)
{
var oXmlSerializer = new XmlSerializer(obj.GetType());
var oStringWriter = new StringWriter();
var oXmlSerializerNamespaces = new XmlSerializerNamespaces();
oXmlSerializerNamespaces.Add(string.Empty,string.Empty);
var oXmlWriterSettings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = false,
Encoding = Encoding.GetEncoding("ISO-8859-1")
};
var oXmlWriter = XmlWriter.Create(oStringWriter,oXmlWriterSettings);
oXmlSerializer.Serialize(oXmlWriter, obj, oXmlSerializerNamespaces);
oXmlWriter.Close();
return oStringWriter.ToString();
}
1 Answer 1
StringWriter
andXmlWriter
are bothIDisposable
hence their usage should be wrapped in ausing
statementThe prefixing
o
of your local variables smells a bit of hungarian notation which generally does not convey a lot of useful information.The encoding has already been mentioned in the comments. In .NET strings are UTF-16 so you use should that instead.
Generally try to declare your variables as close to the point of use as possible. That way it's more obvious from which point on they are being used.
Refactored code:
public static string ObjectToXml(object obj)
{
var settings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = false,
Encoding = Encoding.GetEncoding("UTF-16")
};
var namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty,string.Empty);
var serializer = new XmlSerializer(obj.GetType());
using (var stringWriter = new StringWriter())
{
using (var xmlWriter = XmlWriter.Create(stringWriter, settings)
{
serializer.Serialize(xmlWriter, obj, namespaces);
}
return stringWriter.ToString();
}
}
Update: As pointed out in the comments the suggested refactored code violates point 4 above. This is because I usually try to limit the scope of using
blocks so it's easier to see what's going on there.
As pointed out by Jesse you could make some of the local variables class static as they are always the same. If you put generics in the mix then you could also make the serializer class static and the total refactored code could look like this:
public static class SerializerHelper<T>
{
private static XmlSerializer _Serializer;
private static XmlWriterSettings _XmlSettings;
private static XmlSerializerNamespaces _Namespaces;
static SerializerHelper()
{
_Namespaces = new XmlSerializerNamespaces();
_Namespaces.Add(string.Empty,string.Empty);
_XmlSettings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = false,
Encoding = Encoding.GetEncoding("ISO-8859-1")
};
_Serializer = new XmlSerializer(typeof(T));
}
public static string ObjectToXml(T obj)
{
using (var stringWriter = new StringWriter())
{
using (var xmlWriter = XmlWriter.Create(stringWriter, _XmlSettings))
{
_Serializer.Serialize(xmlWriter, obj, _Namespaces);
}
return stringWriter.ToString();
}
}
}
-
\$\begingroup\$ Since the
settings
and thenamespaces
aren't going to change between calls, it might prove better performance-wise to pull them out asprivate static readonly
class-level members (obviously callnamespaces.Add()
from the static constructor). \$\endgroup\$Jesse C. Slicer– Jesse C. Slicer2014年09月30日 18:59:23 +00:00Commented Sep 30, 2014 at 18:59 -
\$\begingroup\$ Didn't you "violate" point 4 ? \$\endgroup\$Heslacher– Heslacher2014年10月01日 05:14:24 +00:00Commented Oct 1, 2014 at 5:14
-
1\$\begingroup\$ @Heslacher yeah I noticed that after I posted. I guess it conflicts to some degree with trying to limit the scope of the using block \$\endgroup\$ChrisWue– ChrisWue2014年10月01日 06:27:04 +00:00Commented Oct 1, 2014 at 6:27
ISO-8859-1
as the encoding. UseUTF-8
instead. It compresses as much for English but supports all languages. \$\endgroup\$string
which is always UTF-16. \$\endgroup\$UTF-16
though. I do not program inC#
. \$\endgroup\$